# Ocre > Ocre is a Rails-like Rust web framework for Cloudflare Workers, designed to run on the Workers free plan and to be written by AI agents: generators write plain, readable Rust (models, controllers, templates, migrations) into your app, and the `ocre` CLI builds, runs and deploys it. Every page below is Markdown; the HTML version is the same URL without `.md`. Each page is self-contained: prerequisites, complete code, commands and expected output. All pages in one file: https://ocre.rs/llms-full.txt. The generated app's AGENTS.md holds the conventions an agent must follow. ## Getting started - [Installation](https://ocre.rs/getting-started/installation.md): This page installs the tools an Ocre app needs (Rust through rustup with the WebAssembly target, Node.js 22 for Cloudflare's `cf` CLI, and the `ocre` CLI), checks the installation, and creates a first app with `ocre new`, either through the guided setup or with flags. - [Tutorial: a live Q&A app](https://ocre.rs/getting-started/tutorial.md): This tutorial builds a live Q&A app with Ocre, step by step: hosts sign up and create events, anyone with an event's link asks questions and votes for them, and the list reorders live on every open screen over WebSockets. Along the way it covers generators, accounts, ownership checks, realtime channels, validations, request tests and a deploy to the Cloudflare Workers free plan. ## Guides - [Models and migrations](https://ocre.rs/guides/models.md): A model is a generated Rust file, `src/models/.rs`, that holds every query and rule about one D1 table, and migrations are numbered SQL files that create and change those tables. This page explains the generated model section by section (queries, callbacks, associations, enums), the `ocre::Query` builder, transactions, how to change the schema and undo a change, encrypted columns, several databases, and what is not supported. - [Validations](https://ocre.rs/guides/validations.md): Validations check input before it reaches the database: `ocre::Validator` collects every failed rule with Rails' messages, and `finish()` turns them into `Error::Invalid`, a 422 that HTML forms show next to the typed values and JSON APIs report per field. This page lists every check, where rules belong, and what clients receive. - [Controllers and routing](https://ocre.rs/guides/controllers.md): Controllers in Ocre are plain axum handlers grouped in one module per resource, each with a `routes()` function merged into the router in `src/lib.rs`, and a `paths` module that builds the URLs of its pages. This page walks through the generated scaffold controller, then covers routing (nested resources, namespaces, redirects), what a handler can read from the request and answer, error pages, and middleware. Templates and forms are in [Views, helpers and forms](https://ocre.rs/guides/views.md), interactivity in [htmx](https://ocre.rs/guides/htmx.md), CSS and JavaScript in [Assets](https://ocre.rs/guides/assets.md). - [Views, helpers and forms](https://ocre.rs/guides/views.md): Views in Ocre are [askama](https://askama.readthedocs.io/) templates compiled into the Worker: a template is a Rust struct whose fields are the template's variables, so a typo in a variable name or a missing value is a compile error, not a blank page in production. This page covers layouts and partials, the view helpers (numbers, dates, text), forms with validation errors, and responses in other formats (XML, CSV, plain text). Interactivity with htmx has its own page, [htmx](https://ocre.rs/guides/htmx.md). - [htmx](https://ocre.rs/guides/htmx.md): Ocre pages get their interactivity from [htmx](https://htmx.org): HTML attributes send requests, and the HTML fragments handlers answer are swapped into the page. There is no JavaScript to write or build for the common cases, every page still works without JavaScript, and handlers stay ordinary axum handlers rendering askama templates. This page covers boosted navigation (Rails' Turbo Drive), partial responses (Turbo Frames), inline editing, validation as you type, live search, infinite scroll and redirects from htmx requests. - [Assets](https://ocre.rs/guides/assets.md): Files in an Ocre app's `public/` directory are served by [Workers Static Assets](https://developers.cloudflare.com/workers/static-assets/): Cloudflare answers them from its edge before the Worker runs, so they cost no Worker request, no CPU and no free-plan quota. There is no asset pipeline to run: a file in `public/` is deployed as it is by `ocre deploy`, and build tools (Tailwind, esbuild) are optional steps that write into `public/`. This page covers serving, caching, CSS and JavaScript tooling, and single-page apps. - [JSON APIs and GraphQL](https://ocre.rs/guides/json-apis.md): The `ocre g api` generator writes a JSON REST resource under `/api/` whose handlers call the model, and `--graphql` exposes the same resource on `/graphql`; errors are JSON with the HTTP status, field errors included. This page covers the generated API, hand-written JSON endpoints, GraphQL, API-only apps and cross-origin clients. - [Sessions, flash and security](https://ocre.rs/guides/security.md): This guide shows how an Ocre app keeps per-visitor state in an encrypted session cookie, shows one-time flash messages, and what `ocre::serve` does for every request to protect it: host checks, cross-site request (CSRF) checks, CORS, security headers and cookie flags. It then covers the helpers an app calls itself (rate limiting, safe queries and parameters, files, user HTML) and ends with what is not included, so you know what to add yourself. - [Authentication](https://ocre.rs/guides/authentication.md): This guide adds users to an Ocre app with `ocre g auth`: sign-up, login ("remember me") and logout pages, magic links, password resets and email confirmation by email, account deletion, rate limits, JWTs and API keys for JSON clients, and optionally sessions tracked in D1 (`--db-sessions`) and "Continue with GitHub / Google" (`--oauth`). It then shows how to protect pages and endpoints and restrict records to their owner. All of it is generated app code you can read and change; the framework only provides small primitives (password hashing, tokens, JWTs, rate limits, OAuth). - [Email](https://ocre.rs/guides/email.md): This guide sends email from an Ocre app with `ocre::mail` (built directly, or by a mailer generated with `ocre g mailer`, with layouts, app-wide defaults and previews), adds several recipients, headers, attachments and inline images, picks a delivery adapter for development and production, sends from the background with `deliver_later`, inspects every email in `ocre dev`, and receives email through Cloudflare Email Routing with `ocre g mailbox`. - [Web push notifications](https://ocre.rs/guides/push.md): A push notification reaches a user whose page of the app is closed: "your video is ready". The browser subscribes once, the app keeps its subscription, and when something happens the app posts an encrypted message to the browser's push service (Google's for Chrome, Apple's for Safari, Mozilla's for Firefox), which wakes the app's service worker to show it. Sending is free: a subrequest from the Worker to the push service. - [Background jobs and schedules](https://ocre.rs/guides/jobs.md): This guide moves slow or retryable work out of requests with background jobs on Cloudflare Queues (`ocre g job`, `perform_later`, `ocre::jobs::enqueue_all`), explains retries, discarding, the dead-letter queue and idempotency, gives urgent jobs their own queue, and runs tasks on a timetable with Cron Triggers (`ocre g schedule "every day at 3am"`, `ocre schedules`), all within the Workers free plan. - [File storage](https://ocre.rs/guides/files.md): Ocre stores uploaded files in Cloudflare R2 and describes each one with four columns of the record that owns it, like Active Storage without its extra tables. This page covers `attachment` fields, the code the generators write for them, the `ocre::storage` API for custom upload and download handlers, direct browser-to-R2 uploads and downloads through presigned URLs, file analysis, image variants, and what all of it costs on the free plan. - [Webhooks and external services](https://ocre.rs/guides/webhooks.md): A payment provider confirms a payment, a GPU service reports that a job finished, a mail service reports a bounce: each calls the app back with an HTTP POST, a webhook. Ocre checks the signature of the call, keeps a log of the events received, and runs each event's effect once, however many times the sender delivers it. `ocre::webhooks` also signs the calls the app makes, so a service can check them the same way. - [Realtime](https://ocre.rs/guides/realtime.md): Ocre pushes HTML to open pages over WebSockets, like Rails' Action Cable and Turbo Streams: handlers and jobs broadcast fragments to a named channel, and htmx swaps them into every page subscribed to it. This page covers the `--realtime` scaffold, how channels run on a hibernating Durable Object, the broadcast helpers, authorization of channels, and what it costs on the free plan. - [Caching](https://ocre.rs/guides/caching.md): Ocre has opt-in caching tools chosen for the Workers free plan: `ocre::cache` keeps slow or costly results (JSON values or rendered HTML fragments) in Workers KV, every request remembers its own `SELECT` results and KV reads, and `CacheControl`, `ETag` and `Conditional` let browsers reuse pages with `304 Not Modified` answers. This page shows them, the KV write budget that limits the first, and why Ocre does not wrap Cloudflare's own page caches. - [Translations](https://ocre.rs/guides/i18n.md): Ocre translates an app Rails-style: strings live in `locales/.yml` files compiled into the Worker, handlers take the `I18n` extractor for the request's locale, and templates call `i18n.t("key")` with `%{name}` values and CLDR plural forms. This page covers `ocre g locale`, the locale file format, how the locale of a request is chosen, missing keys and defaults, scoped keys, HTML in translations, dates, numbers, model and attribute names, validation messages, the built-in translations, `ocre i18n missing`, and translations outside requests. - [Errors, logging and debugging](https://ocre.rs/guides/debugging.md): This page shows how an Ocre app logs (levels, request-scoped fields, JSON lines for Workers Logs), how errors become HTTP responses, how to report them to a service such as Sentry, what the development error page and the `Server-Timing` header show, how to read a deployed Worker's logs with `ocre logs`, and how to debug a Worker, which has no interactive debugger. - [Testing an Ocre app](https://ocre.rs/guides/testing.md): An Ocre app is tested in four layers: native `cargo test` for code that touches no Cloudflare binding, `cargo check --target wasm32-unknown-unknown` for the real build, request tests that talk HTTP to the app running in workerd, and browser tests (Playwright) for pages with JavaScript. Generators write the tests for what they generate; `ocre test` runs the first two layers, `ocre test --e2e` all four, against a fresh test database. - [Deployment](https://ocre.rs/guides/deployment.md): The `ocre deploy` command builds the app in release mode, creates the Cloudflare resources it is missing, applies the D1 migrations and publishes the Worker on `workers.dev`. This page explains each step, how to set production variables and secrets, run commands on the production database, roll back, add a custom domain, read logs and deploy from CI. - [Upgrading from wrangler.toml](https://ocre.rs/guides/upgrading.md): Earlier versions of Ocre generated apps configured by a `wrangler.toml` and ran `npx wrangler` for everything. Ocre now drives Cloudflare's [`cf` CLI](https://www.npmjs.com/package/cf) and reads `cloudflare.config.ts`. This page converts an existing app, step by step: Cloudflare's own converter (`cf migrate`) does most of it, then a few Ocre-specific fixes finish the job. - [Migrating from Postgres](https://ocre.rs/guides/postgres.md): D1 is SQLite. An app moving from Postgres (Rails, Phoenix, Django) brings its tables and rows over with one command, then adapts what SQLite does differently. ## Reference - [CLI commands](https://ocre.rs/reference/cli.md): This page documents every `ocre` command and flag, what each one does step by step, its human and `--json` output, and the errors it reports with their hints. Code generators (`ocre g ...`) have their own page, [Generators](https://ocre.rs/reference/generators.md). - [Generators](https://ocre.rs/reference/generators.md): This page documents every `ocre g` generator: its arguments and flags, the naming rules, the files it creates and updates, what the generated code contains, and its errors. Generators write plain Rust, SQL and templates into the app, which the app then owns and edits. - [Field types](https://ocre.rs/reference/field-types.md): This page lists every field type the `ocre g model`, `ocre g scaffold`, `ocre g api`, `ocre g resource` and `ocre g migration` generators accept, with the SQL column, Rust types, serde attributes, form input, JSON and GraphQL representation and validations each one produces, plus the `?` (optional) and `^` (unique) modifiers and the names that are refused. - [Configuration](https://ocre.rs/reference/configuration.md): This page describes every configuration file of an Ocre app (`cloudflare.config.ts`, `wrangler.config.ts`, `package.json`, `tsconfig.json`, `.dev.vars`, `Cargo.toml`, `rust-toolchain.toml`), the binding names Ocre requires, and each Worker variable and secret the `ocre` crate reads, with its format, default, where to set it in development and production, and the error when it is missing. - [Free-plan limits](https://ocre.rs/reference/limits.md): This page lists the Cloudflare Workers Free plan limits that matter to an Ocre app, as published by Cloudflare in September 2026, with the source of each value and what Ocre does about it. - [API index](https://ocre.rs/api-index.md): Every public item of the `ocre` crate (all features) with its path, signature and first doc sentence, grouped by module. Full documentation: the rustdoc pages, or `cargo doc -p ocre --all-features --open`. ## Explanations - [Architecture](https://ocre.rs/explanations/architecture.md): An Ocre app is one Rust crate compiled to WebAssembly and run as a single Cloudflare Worker, with `ocre::serve` wrapping a plain axum router. This page follows a request through the app, maps each Ocre feature to the Cloudflare product behind it, and explains the WebAssembly constraints that shape the framework. - [Why generated code](https://ocre.rs/explanations/generated-code.md): Ocre's generators write models, controllers, templates and migrations into your app as plain Rust files that you own, instead of hiding them behind macros, derives or an ORM. This page explains why, how generators change files that already exist, what the approach costs, and how it compares with Rails and Loco. - [Security model](https://ocre.rs/explanations/security-model.md): Ocre protects every app by default against session tampering, cross-site request forgery, clickjacking, MIME sniffing and leaked error details, and the code `ocre g auth` generates adds password, token, JWT and API-key handling built on small framework primitives. This page describes each protection as the code implements it, the reasons behind the choices, and what is left to you. - [Cost model](https://ocre.rs/explanations/cost-model.md): This page explains how an Ocre app spends the Cloudflare Workers Free plan: what counts as a request, where the 10 ms of CPU per request go, what each generated query costs in D1 rows, why KV writes are the scarcest resource, what a background job costs in Queues operations, and when a growing app should move to Workers Paid. ## Optional - [Rustdoc API reference](https://ocre.rs/api/ocre/): every public item of the `ocre` crate (all features), generated by `cargo doc`; HTML only, prefer api-index.md.