File Storage That Just Works
Upload files. Parse documents. Index content for AI search. Serve with download grants. Local or cloud — FLIN handles it all. No S3 buckets, no CDN configuration, no storage SDKs.
File Upload
The file field type on any entity enables file uploads. Files are stored in .flindb/blobs/ with content-addressable hashing. No configuration needed.
Document Parsing
Upload a PDF, DOCX, or CSV — FLIN extracts the text automatically via document_extract(). Nine formats supported out of the box. Feed parsed content directly into semantic search.
Cloud Backends
Start with local storage. Scale to AWS S3, Cloudflare R2, or Google Cloud Storage with one config change. Signed URLs, download grants, and shareable links — all built in.
How It Works
Add a file field to any entity. Upload through forms or API routes. Files are stored and served — that is the entire setup.
entity Document { title: text @required attachment: file // Basic file storage content: semantic file // Auto-parsed + AI-searchable category: text = "general" } // Upload via API route with validation route POST /documents { guards { auth: required } validate { title: text @required content: file @required @extension(".pdf", ".docx") @max_size("50MB") } doc = Document { title: body.title, content: body.content } save doc response.created(doc) } // Upload via form <form method="POST" action="/documents" enctype="multipart/form-data"> <input type="file" name="content" /> <button type="submit">Upload</button> </form>
Two File Types, Two Superpowers
file stores any file. semantic file parses, chunks, embeds, and indexes — making documents AI-searchable on save.
// Store any file as-is avatar: file // Access properties doc.avatar.name // Original filename doc.avatar.size // Size in bytes doc.avatar.type // MIME type doc.avatar.extension // File extension // Serve it <img src={doc.avatar} /> <a href={doc.avatar}>Download</a>
// Parse + embed + index on save report: semantic file // Text extraction (automatic) // PDF → text, DOCX → text, etc. // AI search across files results = search "budget Q4" in Document by report // RAG: ask questions about files answer = ask_ai("Summarize the budget", ["context": results])
9 Document Formats, One Function
document_extract(file) extracts text from any supported document. No external parsers, no system dependencies, no cloud APIs.
Text extraction from standard PDF files
.pdfDOCX
Microsoft Word documents
.docxHTML
Web pages, exported articles
.htmlCSV
Spreadsheet and tabular data
.csvXLSX
Excel spreadsheets
.xlsxJSON
Structured data files
.jsonYAML
Configuration and data files
.yamlRTF
Rich text documents
.rtfXML
Structured markup documents
.xmlFile Validators
Control file uploads with declarative validators. Enforced on every save — no bypass possible.
@max_size(max)
Limit maximum file size. Supports KB, MB, GB units. Example: @max_size("50MB")
@mime_pattern("type")
Restrict by MIME type with wildcards: @mime_pattern("image/*"), @mime_pattern("application/pdf")
@extension("ext")
Restrict by file extension: @extension(".pdf", ".doc", ".docx")
@min_size(min)
Enforce minimum file size to reject empty uploads: @min_size("1KB")
@image
Shorthand for image files only. Equivalent to @mime_pattern("image/*")
@document
Shorthand for document files: PDF, DOCX, XLSX, CSV, and other text-extractable formats.
Local to Cloud in One Config Change
Start with local storage. When you outgrow it, switch to any cloud provider without changing a single line of application code.
Local (Default)
Files stored in .flindb/blobs/ with content-addressable hashing. Zero configuration. Move the app, the files move with it.
AWS S3
Amazon S3 with region configuration. Signed URLs for secure downloads. Set AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY.
Cloudflare R2
S3-compatible object storage with zero egress fees. Same API, lower cost. Perfect for media-heavy applications.
Google Cloud Storage
GCS buckets with automatic lifecycle management. Signed URLs and IAM-based access control.
# Local storage (default — zero config) storage { backend: "local" } # AWS S3 storage { backend: "s3" bucket: "my-app-files" region: "us-east-1" } # Cloudflare R2 storage { backend: "r2" bucket: "my-app-files" account_id: "abc123" }
Download Grants and Secure Sharing
Control who can download files, how many times, and for how long. Generate signed URLs and password-protected download links.
// Generate a download grant with restrictions grant = doc.attachment.grant( max_uses: 5, // Limit to 5 downloads expires: 1.day, // Expires in 24 hours password: "secret123" // Require password ) download_url = grant.url // Or use signed URLs (time-limited, no password) signed = doc.attachment.signed_url(3600) // Valid for 1 hour // Or a permanent shareable link link = doc.attachment.shareable_url()
Time-Limited
Signed URLs expire after a configurable duration. No permanent public links unless you want them.
Use-Limited
Set a maximum number of downloads per grant. After the limit, the link stops working.
Password-Protected
Require a password to download. Perfect for sharing sensitive documents with external parties.
Storage Architecture
Content-addressable blob storage with SHA-256 hashing. Duplicate files are stored once. Integrity verified on every read.
.flindb/ ├── wal.log # Write-ahead log ├── schema.json # Entity schemas ├── blob_refs.json # Reference tracking index ├── data/ │ ├── Document.flindb # Document records │ └── User.flindb # User records ├── blobs/ # Content-addressable file storage │ └── {shard}/{hash}/ │ ├── data.pdf # Original file │ ├── preview_100.webp │ ├── preview_300.webp │ └── preview_800.webp ├── semantic/ # Vector embeddings │ └── vs_config.json └── backups/ └── backup-2026-02-16.flindb
Admin Console Integration
The built-in admin console at /_flin includes full file management with category tracking, size monitoring, and one-click downloads.
Category Breakdown
See how storage is distributed across entity types: images, documents, uploads by category — all in real time.
Size Tracking
Total storage used, per-category sizes, and individual file sizes. Monitor growth and plan capacity.
File Browser
Browse, download, and delete files directly from the admin console. No FTP, no shell access, no cloud dashboard needed.
No S3. No CDN. No Cloud Storage API.
Traditional stacks require AWS S3, Google Cloud Storage, and a CDN for file serving. FLIN handles it all — from local development to cloud production — with zero configuration changes to your application code.