Zum Inhalt springen
GigadriveDocs

TypeScript configuration

Write your deployment configuration as gigadrive.ts, with editor type checking and values your own code computes.

gigadrive.ts holds the same configuration gigadrive.yaml does, written as a TypeScript module the build executes. Your editor checks the keys as you type, and the file can build parts of the configuration from your own code instead of listing them by hand.

Set it up

  1. Install the config package

    The package supplies the types. Keep it as a dev dependency.

    npm install --save-dev @gigadrive/network-config
  2. Write gigadrive.ts at the project root

    Export the configuration object as the default export, and type it with ConfigV4.

    import type { ConfigV4 } from '@gigadrive/network-config';
    
    export default {
      version: 4,
      assets: 'public',
      functions: {
        'api/report.js': {
          runtime: 'node-22',
          memory: 1024,
          max_duration: 120,
        },
      },
      routes: [
        {
          source: '^/api/report(/.*)?$',
          destination: 'api/report.js',
          methods: ['GET', 'POST'],
        },
      ],
    } satisfies ConfigV4;
  3. Delete the file it replaces

    Keep one configuration file. gigadrive.ts is found before gigadrive.yaml, so leaving both in the repository means the YAML is silently ignored and nothing says so. gigadrive debug config prints the path that answered.

version: 4 is still required and is still a number. Every other key is the one Configuration reference documents, spelled the same way, including the snake_case names such as max_duration and build_commands.

Type checking and autocomplete

import type is the form to reach for. TypeScript erases it before the file runs, so ConfigV4 costs the deployment nothing and satisfies still gives you autocomplete, a red squiggle on a misspelled key, and a rejection of a memory outside 128 to 3009 or a runtime that does not exist.

The package also exports defineConfig, an identity function that types its argument the same way:

import { defineConfig } from '@gigadrive/network-config/define-config';

export default defineConfig({
  version: 4,
  assets: 'dist',
});

Import it from the @gigadrive/network-config/define-config subpath rather than the package root. The subpath ships its own type declarations and imports nothing else, while the package root pulls in effect and @effect/platform as peer dependencies that not every package manager installs for you.

Computing the configuration

The file is executed, so a value can come from your own code rather than from a literal. This is the reason to pick TypeScript over YAML: a project whose entrypoints or routes are already described somewhere in the repository can derive them instead of repeating them.

import type { ConfigV4 } from '@gigadrive/network-config';

import { endpoints } from './src/endpoints';

export default {
  version: 4,
  assets: 'public',
  functions: Object.fromEntries(endpoints.map((endpoint) => [endpoint.file, { runtime: 'node-22', memory: 512 }])),
  routes: endpoints.map((endpoint) => ({
    source: endpoint.path,
    destination: endpoint.file,
  })),
} satisfies ConfigV4;

Relative imports resolve from the config file's own directory, so ./src/endpoints works from a gigadrive.ts beside it. Everything at the top level of the file runs when the deployment reads the configuration, on the same trust footing as a build command.

Two inputs are not available to that code, and a file that depends on either behaves differently on your machine than it does on a deployment:

  • Environment variables. The configuration is read outside the environment your build runs in, so process.env holds none of the variables you set for the application. Environment variables covers what does reach a build and a Function.
  • Installed packages. A deployment reads the configuration from the fetched source, before the install step, and reads it again after your build. An import that resolves inside your repository works at both points. An import of a package from node_modules resolves only at the second one.

The other extensions

The same module handling applies to five more filenames, so a project that is not written in TypeScript still gets the executable form:

FilenameExport with
gigadrive.ts, gigadrive.mts, gigadrive.mjsexport default
gigadrive.js, gigadrive.cjs, gigadrive.ctsmodule.exports =, or export default in an ESM project

.cjs and .cts are CommonJS by definition, so they are read through the interop path and module.exports is what they export. The three ESM-only extensions need a real default export, and a file carrying only named exports is reported as having none.

// gigadrive.cjs
module.exports = {
  version: 4,
  assets: 'dist',
};

Configuration lists every accepted filename in the order the build checks them.

What the export has to be

The default export has to be the configuration object itself. A function is rejected on purpose, so there is no hook for deciding the configuration at the moment the deployment reads it. Arrays, strings and numbers are rejected too.

MessageCause
Config file is empty at ...The file has no contents. Checked before it is evaluated
Failed to load config module at ...A syntax error, an import that does not resolve, or a top-level statement that threw
... does not have a default exportA .ts, .mts or .mjs file with only named exports
... config factories are not supportedThe default export is a function
... must default-export a config objectThe default export is a string, a number or an array
Config file is missing version at ...The exported object has no version, or its version is not a number

A file that loads and exports an object goes through the same schema validation as YAML, so a bad value inside it fails the build with the path to that value.

Migrating from gigadrive.yaml

Translate the YAML into an object literal, keeping every key name as it was, and delete the YAML file:

version: 4
assets: public
functions:
  api/report.js:
    runtime: node-22
    memory: 1024
import type { ConfigV4 } from '@gigadrive/network-config';

export default {
  version: 4,
  assets: 'public',
  functions: {
    'api/report.js': {
      runtime: 'node-22',
      memory: 1024,
    },
  },
} satisfies ConfigV4;

Run gigadrive debug config afterwards. It resolves the configuration through the same code path a deploy uses and prints the result, so you can compare it against what the YAML produced before you deploy. Debugging configuration covers the output.