Documentation
ohne is a zero-dependency TypeScript framework for the web. It gives you a database, an HTTP API, internationalization, and a dashboard, with no build step. The framework ships .ts source, your app is .ts source, and Node 26 runs both directly. What you write is what runs.
Start here
New to ohne? Read these in order:
Project
How a project is put together - the config file, the CLI, and the layer system that lets one project extend another.
- Configuration
ohne.config.tsand the core settings it holds. - The CLI
npm create ohneand everyohnecommand. - CommandsAdd your own
ohnecommands for work outside a request. - Environment variablesThe built-ins and how to define your own.
- Boot filesCode that runs before the server opens.
- HooksRun code at fixed points in the framework, or change what it produces.
- LayersStack projects as packages and override what they ship.
- MonorepoYour ohne app and your Nuxt or Next website in one repository.
- TestingRun your app's tests with Node's test runner.
Database
Declare your data as collections of fields. ohne keeps the schema in sync with your code and gives you a typed query builder for reads and writes.
- Collections and fieldsYour data model, and the built-in field types it is made of.
- Field typesEvery field type ohne ships, with all of its options.
- Custom field typesDefine a field type once, use it in any collection.
- Conditional fieldsFields that are active only when a condition is true.
- BlocksOrdered lists of mixed, reusable shapes.
- Rich textFormatted text with links to addresses and records.
- TranslationsOne value per locale.
- Reading recordsThe fluent query builder: filter, sort, paginate, populate.
- Writing recordsCreate, update, and delete.
- Schema syncHow your collections become tables, safely.
- MigrationsIntentional data changes the sync guard would refuse.
- The database engineSQLite, Postgres, connections, and raw SQL.
- Cluster locksRun work exactly once across instances.
HTTP API
Define endpoints as files. Handlers read the request and return a value ohne serializes for you.
- RoutesThe file convention and
defineHandler. - Reading the requestParams, search params, body, cookies, negotiation.
- Shaping the responseStatus, headers, redirects, caching, files, events.
- HTTP errors
HTTPErrorand the JSON body a client receives. - MiddlewareCode that runs before the handler on every matching request.
- Rate limitingCap how often one client may call a route.
- Querying over HTTPTurn a URL query into a safe, filtered read.
- The collections APIREST endpoints a collection opts into.
Auth
Email and password accounts, sessions, roles, and the helpers to protect a route. Shipped by the ohnejs/base layer, so an app opts out by not stacking it.
Internationalization
Two independent systems: message catalogs for your UI strings, and content locales for your data (covered in translations).
Dashboard
A browser UI for your app, served by ohne with no build step. Pages are .ts modules that ship to the browser as type-stripped JavaScript.
- Dashboard pagesThe pages convention, navigation, the sidebar, and how pages are served.
- Rendering
h,mount,each, andwhen. - Reactivity
ref,computed, andeffect. - Data in the dashboardThe typed
api()fetch helper and translations. - Your first pageBuild a page step by step: stats, a chart, a table, and a form.
- ComponentsThe kit at a glance, and the grammar every component shares.
- Layout
page, sections, stacks, rows, grids, and splits. - Cards and tabsCards, tabs, and disclosures.
- ActionsButtons, button groups, selects, menus, context menus, and copy buttons.
- DisplayBadges, status, icons, alerts, facts, lists, meters, and states.
- FeedbackToasts, confirmations, and dialogs.
- TablesTyped rows with sorting, paging, selection, and row actions.
- Stats and chartsStat tiles, line, bar and donut charts, bar lists, and funnels.
- FormsTyped page forms with
form,field,fieldInput, andformField. - Field layoutsRows, cards, tabs, and rules for every form the dashboard renders.
- Account settingsEach user's language, time zone, date and time formats, and smart clipboard.
- Search paletteCmd+K search across records and pages.
- Table bookmarksSave a table's view, share it, and open on it by default.
Uploads
An optional layer for files: storage with a backend you can replace, an Uploads collection, upload and serve routes, media fields, and the dashboard's Media page.
- UploadsInstall the layer, configure storage, upload and serve files.
- Uploading from a URLFetch a file from a link into Media.
- StorageThe filesystem, S3, or a backend of your own.
- Resumable uploadsSend a large file in chunks, and continue after a lost connection.
- Media fieldsReference uploads from your collections.
- Image variantsSigned URLs an image service renders on demand.
- Private filesFiles that open only through an expiring link or for a signed-in reader.
- The image serviceThe protocol a service follows to render variants.
CMS
An optional layer that makes your app the CMS for a website built with any framework, with a live editor that shows the website as you type.
- The CMSInstall the layer, map paths to collections, and edit pages live.
- Your websiteRead pages with
@ohnejs/clientand join the live preview. - FrameworksThe whole loop in Nuxt, Next, React, and plain HTML.
- SEO and redirectsSite settings, page SEO, redirects, sitemap, and
robots.txt. - WebhooksTell a caching website when pages change.
Assistant
An optional layer that puts an assistant behind Cmd+K. It proposes requests, the person approves them, and their own browser sends them, so it never does more than the person can.
- The assistantInstall the layer, pick models, choose what it may see.
- TransformsTranslate and rewrite text, with every change reviewed.
- SkillsTeach the assistant one kind of work.
- FlowsRoute a question through decide and act steps.
- Assistant policyThe prompts, routes and denied collections, all yours to change.
Production
Your app deploys as the source you wrote, with no build step.