Typed schema. Migrations on save.
Declare entities in TypeScript with field.string / int / datetime / id and composite indexes. Pylon diffs the schema and applies migrations automatically. SQLite is the one-file default. Point DATABASE_URL at Postgres and the same schema follows.
import { entity, field } from "@pylonsync/sdk"; const Room = entity("Room", { slug: field.string(), name: field.string(), createdAt: field.datetime(),}); const Message = entity("Message", { roomId: field.id("Room").readonly(), authorId: field.id("User").readonly(), body: field.string(), createdAt: field.datetime().readonly(),});- One fully typed schema file gives your editor every field
- Migrations apply on save in dev; no migration files to hand-author
- SQLite is the default: a single file, nothing to provision
- Set DATABASE_URL=postgres://… and the same schema targets Postgres
How it works.
field.id("Room") is a typed foreign key, field.richtext() carries formatting, field.datetime() is timezone-correct, field.encrypted() is sealed at rest. Add .readonly() to block HTTP PATCH from rewriting identity fields, .index() for composite indexes. The types flow all the way to db.useQuery on the client.
What you’d otherwise wire up.
Each line is a piece teams normally assemble for this one capability. On Pylon it is part of the runtime.
- A migration tool and the version table it owns
- An ORM layer plus whatever generates its types
- A hand-written REST or GraphQL API over your own tables
- Connection wiring between the API service and the database
Apps built with it.
Scaffold any of these with npm create @pylonsync/pylon.
One entity, one function, one page. Start from a clean slate.
Build it on Pylon.
One framework for your schema, sync, auth, functions, realtime, and SSR. Free to start.