Skip to content

hatk is configured through hatk.config.ts at the project root. The defineConfig helper provides type safety and autocompletion.

Minimal example

Most projects only need a few options. Here is a minimal config that works for local development:

typescript
import { defineConfig } from '@hatk/hatk/config'

export default defineConfig({
  port: 3000,
  database: 'data/hatk.db',
  oauth: {
    clients: [
      {
        client_id: 'http://127.0.0.1:3000/oauth-client-metadata.json',
        client_name: 'My App',
        redirect_uris: ['http://127.0.0.1:3000/oauth/callback'],
      },
    ],
  },
})

Production example

A real-world config that switches between local and production settings:

typescript
import { defineConfig } from '@hatk/hatk/config'

const isProd = process.env.NODE_ENV === 'production'
const prodDomain = process.env.RAILWAY_PUBLIC_DOMAIN

export default defineConfig({
  relay: isProd ? 'wss://bsky.network' : 'ws://localhost:2583',
  plc: isProd ? 'https://plc.directory' : 'http://localhost:2582',
  port: 3000,
  database: isProd ? '/data/hatk.db' : 'data/hatk.db',
  backfill: {
    parallelism: 5,
    signalCollections: ['xyz.statusphere.status'],
  },
  oauth: {
    issuer: isProd && prodDomain ? `https://${prodDomain}` : undefined,
    scopes: ['atproto'],
    clients: [
      ...(prodDomain
        ? [{
            client_id: `https://${prodDomain}/oauth-client-metadata.json`,
            client_name: 'My App',
            redirect_uris: [`https://${prodDomain}/oauth/callback`],
          }]
        : []),
      {
        client_id: 'http://127.0.0.1:3000/oauth-client-metadata.json',
        client_name: 'My App',
        redirect_uris: ['http://127.0.0.1:3000/oauth/callback'],
      },
    ],
  },
})

Server options

OptionTypeDefaultEnvDescription
relaystring'ws://localhost:2583'RELAYWebSocket URL for the AT Protocol firehose relay. Use wss://bsky.network in production.
plcstring'https://plc.directory'DID_PLC_URLPLC directory URL for DID resolution. Use http://localhost:2582 for local dev.
portnumber3000PORTHTTP port for the hatk backend server.
publicDirstring | null'./public'--Directory for static files. Set to null to disable static file serving.
collectionsstring[][]--Collection NSIDs to index. If empty, auto-derived from your lexicon record definitions.
adminsstring[][]ADMINSDIDs allowed to access /admin/* endpoints. Env var is comma-separated.

Database options

OptionTypeDefaultEnvDescription
databasestring':memory:'DATABASESQLite database file path, resolved relative to the config file. Use an absolute path in production (e.g., /data/hatk.db).

Backfill options

The backfill object controls how the server catches up on historical data from the AT Protocol network.

OptionTypeDefaultEnvDescription
backfill.parallelismnumber3BACKFILL_PARALLELISMNumber of concurrent repo fetches.
backfill.fetchTimeoutnumber300BACKFILL_FETCH_TIMEOUTTimeout per repo fetch in seconds.
backfill.maxRetriesnumber5BACKFILL_MAX_RETRIESMax retry attempts for failed repo fetches.
backfill.fullNetworkbooleanfalseBACKFILL_FULL_NETWORKBackfill the entire network (not just repos that interact with your collections).
backfill.reposstring[]--BACKFILL_REPOSPin specific DIDs to always backfill. Env var is comma-separated.
backfill.signalCollectionsstring[]----Collections that trigger a backfill when a new record appears. Defaults to your top-level collections.
OptionTypeDefaultEnvDescription
ftsRebuildIntervalnumber5000FTS_REBUILD_INTERVALDuckDB only. Rebuild the FTS index every N writes. Lower values mean fresher search results but more CPU usage. SQLite uses incremental FTS updates and ignores this setting.

OAuth options

The oauth object configures AT Protocol OAuth for authenticated endpoints. Set to null or omit entirely to disable auth.

OptionTypeDefaultEnvDescription
oauth.issuerstring'http://127.0.0.1:{port}'OAUTH_ISSUERThe OAuth issuer URL. Typically your server's public URL.
oauth.scopesstring[]['atproto']--OAuth scopes to request. Use granular scopes to limit access (e.g., 'repo:xyz.statusphere.status?action=create&action=delete').
oauth.clientsOAuthClientConfig[][]--Allowed OAuth clients. Each entry needs client_id, client_name, and redirect_uris.
oauth.cookieNamestring'__hatk_session'--Name of the session cookie.

OAuth client fields

Each entry in oauth.clients has:

FieldTypeRequiredDescription
client_idstringYesClient identifier URL (points to your OAuth client metadata JSON).
client_namestringYesHuman-readable name shown during the authorization flow.
redirect_urisstring[]YesAllowed redirect URIs after authorization.
scopestringNoScope override for this specific client.

Environment variable overrides

Every option that lists an Env column can be set via environment variables. Environment variables take precedence over values in hatk.config.ts. This is useful for production deployments where you set secrets and infrastructure-specific values through your hosting platform's environment configuration.