Skip to main content

CLI & Build Tools

GoatDB provides CLI tools for scaffolding and local development, plus programmatic build/dev APIs used from your project scripts.


CLI Commands

init — Scaffold a Project

Creates a complete project structure with a React client, GoatDB server, shared schema, and build tooling.

Deno:

deno run -A jsr:@goatdb/goatdb init
deno run -A jsr:@goatdb/goatdb init ./my-app # optional target directory

Node.js (requires Node.js 24+):

npx -y @goatdb/goatdb init
npx -y @goatdb/goatdb init ./my-app # optional target directory

If you install globally (npm install -g @goatdb/goatdb), you can run goatdb init directly.

Generated structure

After running init, your project looks like this:

my-app/
├── client/
│ ├── index.html # HTML shell served to the browser
│ ├── index.css # Base stylesheet
│ ├── index.tsx # React entry point — registers schemas and mounts <App />
│ └── app.tsx # Root component — start editing here
├── common/
│ └── schema.ts # GoatDB schema definitions — add your schemas here
├── server/
│ ├── debug-server.ts # Development server (port 8080, live reload)
│ ├── server.ts # Production server entry with CLI args
│ └── build.ts # Script to compile to a standalone executable
├── .gitignore # Ignores node_modules, build, server-data, etc.
└── deno.json / package.json # Project config (runtime-dependent)

Node.js only adds package.json, tsconfig.json, .npmrc, and server/server-sea.ts (for embedded binary mode).

Key behaviors

  • Idempotent — existing files are never overwritten, safe to re-run.
  • Auto-installs dependencies — runs deno add or npm install after scaffolding.
  • Runtime auto-detected — produces the correct config files and import paths for whichever runtime invokes it.

Run the dev server

# Deno
deno task dev

# Node.js
npm run dev

Both commands start a server at http://localhost:8080 with live reload on file changes.


Swap your project's GoatDB dependency to point at a local clone. Useful when working on GoatDB itself alongside your app.

note

link/unlink requires Deno to be installed, even for Node.js projects. On Node.js projects it edits package.json to use a file: path, but Deno is still the runtime that executes the command. Contributing to GoatDB's source (not just using it) requires Deno.

# Point project at local GoatDB
deno run -A jsr:@goatdb/goatdb/link link ../path/to/goatdb

# Restore original dependencies
deno run -A jsr:@goatdb/goatdb/link unlink

The /link in the import path is the module entry point; link or unlink is the subcommand passed as the first argument.

  1. Deno projects: Creates vendor/goatdb symlink → local path, rewrites deno.json imports to use the symlink.
  2. Node.js projects: Updates package.json @goatdb/goatdb entry to "file:/absolute/path".
  3. Saves original state to goat.link.json and adds it plus modified config files to .gitignore.

unlink reverses all of this — restores goat.link.json values, removes the symlink, and cleans .gitignore.


Build & Development APIs

These are TypeScript APIs imported from @goatdb/goatdb/server/build and invoked from project scripts, not directly from the command line.

Building Standalone Executables

Packages your app into a single binary with all assets embedded. Invoked programmatically from server/build.ts (generated by init).

import { compile, type CompileOptions } from '@goatdb/goatdb/server/build';

await compile({
serverEntry: './server/server.ts', // Server entry point (required)
jsPath: './client/index.tsx', // React client entry (required)
buildDir: './build', // Intermediate build output (required)
htmlPath: './client/index.html', // HTML template (optional)
cssPath: './client/index.css', // Stylesheet (optional)
outputName: 'my-app', // Binary name, default: "app" (optional)
});

Platform and architecture

await compile({
// ...
os: 'linux', // 'mac' | 'linux' | 'windows'
arch: 'x64', // 'x64' | 'arm64'
});
Cross-compilation

Deno only supports cross-compilation. Running compile on a Mac with os: 'linux' produces a Linux binary.

Node.js builds are always native — run compile on the target OS.

Code signing

await compile({
// ...
signing: {
// macOS
identity: 'Developer ID Application: Your Name (TEAMID)',
hardenedRuntime: true,
entitlements: './entitlements.plist',
notarize: {
keychainProfile: 'my-notarization-profile',
staple: true,
},

// Windows
windows: {
thumbprint: 'ABC123...', // certificate store (preferred)
timestampUrl: 'http://timestamp.digicert.com',
},
},
});

Run compilation

# Deno
deno task compile

# Node.js
npm run compile

Both tasks invoke server/build.ts, which is pre-wired with your project's paths.


Development Server

The development server is scaffolded by init into server/debug-server.ts — you don't need to configure anything. It starts on port 8080 and rebuilds client assets on file changes.

deno task dev   # or: npm run dev

Programmatic use

If you need to embed a debug server in a custom script:

import { startDebugServer } from '@goatdb/goatdb/server/build';
import { registerSchemas } from './common/schema.ts';

registerSchemas();

await startDebugServer({
jsPath: './client/index.tsx',
htmlPath: './client/index.html',
cssPath: './client/index.css',
buildDir: './build',
watchDir: '.', // directory to watch for changes
port: 8080,
orgId: 'dev-org', // simulate a specific org's environment (optional)
setup: async (server) => { // called after init, before HTTP listening (optional)
// access server.db here for event handlers, background tasks, etc.
},
});

Watch options:

OptionDefaultDescription
watchDir'.'Root directory to watch for changes
watchFilterIgnores dotfiles, .tmp files, .git/, node_modules/, build/, server-data/(path: string) => boolean — return true to trigger a rebuild
beforeBuild / afterBuildAsync hooks that run before/after each rebuild

orgId simulates a specific organization's environment locally. setup is called after the server and database are initialized but before HTTP listening begins — use it to access the GoatDB instance for server-side logic (event handlers, background processes, custom endpoints).