TypebaseTypebase

Work Locally

Run your Typebase server on localhost during development.

Last updated on

For most day-to-day work, the simplest setup is to deploy your server to dev once and point your frontend at the deployed URL. Your frontend hot-reloads instantly, and you redeploy the backend with npx typebase-io-cli deploy dev whenever you change it.

But sometimes you want to iterate on server code without redeploying (for debugging, working offline, or just a faster feedback loop). In those cases you can run the server on your own machine.

Generate the server

npx typebase-io-cli generate-server

This writes a runnable server to typebase/_server/. See the generate-server reference for output formats and adapters.

The generated server is a snapshot of your typebase/ directory. It isn't watching your files. Re-run generate-server (and restart the local server) any time you change anything inside typebase/, whether that's an action, your schema, or your auth config.

Start it

cd typebase/_server
npm install
npx tsx src/index.ts

The server listens on http://localhost:8080 by default. Pass --port to generate-server (or set server.port in typebase.json) to use a different port.

generate-server defaults to TypeScript output and the node adapter. If you'd rather run plain JavaScript, pass --output esm or --output cjs and run the built files with node src/index.js.

Environment variables

The generated server reads its config from a .env file in typebase/_server/. At minimum you'll need:

typebase/_server/.env
DATABASE_URL=postgresql://...   # only if your project has a db/schema.ts
BETTER_AUTH_SECRET=...          # only if your project has an auth.ts

The easiest way to get these values is to run npx typebase-io-cli deploy dev or npx typebase-io-cli deploy prod (or the equivalent npx typebase-io-cli db <target> push) once. That provisions the Neon branch, writes the connection string to your project-root .env, and syncs the secrets to your provider.

The generated server reads a plain DATABASE_URL, but the CLI stores both connection strings in your project-root .env under different keys so they can coexist:

  • DATABASE_URL → prod branch
  • DATABASE_URL_DEV → dev branch

For local development, copy whichever branch you want to run against into typebase/_server/.env as DATABASE_URL:

typebase/_server/.env
# running against the dev branch: paste DATABASE_URL_DEV from your project-root .env
DATABASE_URL=postgresql://...

Most of the time you'll want the dev branch so local experiments don't touch production data.

If the value isn't in your project root yet (for example, on a fresh machine), you can fetch it from the provider. Pick the target that matches the branch you want.

Dev branch:

npx typebase-io-cli env dev get DATABASE_URL
npx typebase-io-cli env dev get BETTER_AUTH_SECRET

Prod branch:

npx typebase-io-cli env prod get DATABASE_URL
npx typebase-io-cli env prod get BETTER_AUTH_SECRET

If a command prints ENCRYPTED, that provider is hiding the raw secret value. In that case, copy the value from the original source instead: the Neon console for DATABASE_URL, or the provider dashboard for BETTER_AUTH_SECRET.

Point your frontend at localhost

In your frontend project's .env, override the server URL so your client hits localhost instead of the deployed server:

.env
TYPEBASE_APP_URL=http://localhost:8080

# Or

TYPEBASE_APP_URL_DEV=http://localhost:8080

The CLI stores both deployment URLs in your project-root .env under different keys so they can coexist:

  • TYPEBASE_APP_URL → prod deployment
  • TYPEBASE_APP_URL_DEV → dev deployment

Trusted origins for auth

If you have an auth.ts file, add your frontend's local origin to trustedOrigins so the local server accepts its requests:

typebase/auth.ts
export const auth = defineAuth({
  trustedOrigins: ['http://localhost:3000', 'http://localhost:3001'],
  emailAndPassword: { enabled: true },
});

Use whatever ports your frontend and server actually run on.

Pushing schema changes

You can apply schema changes to your dev Neon branch without doing a full deploy:

npx typebase-io-cli db dev push

This is the same command npx typebase-io-cli deploy dev runs under the hood, so your local server and your next deploy stay on the same schema.

If you'd rather run your local server against a Postgres instance on your own machine (Docker, Postgres.app, etc.) instead of a Neon branch, point db local push at it:

npx typebase-io-cli db local push --url postgres://localhost:5432/mydb

You can also set DATABASE_URL (in your shell or in typebase/_server/.env) and omit the --url flag. See the db local push reference for details.

On this page