Skip to main content
The sync() function generates TypeScript types for all Astro modules in your project. This sets up a src/env.d.ts file for type inferencing and defines the astro:content module for the Content Collections API.
The JavaScript API is experimental and may change in future releases.

Import

import { sync } from 'astro';

Signature

function sync(inlineConfig: AstroInlineConfig): Promise<void>

Parameters

inlineConfig
AstroInlineConfig
required
Configuration object for your Astro project. Supports all options from astro.config.mjs.
inlineConfig.root
string
The root directory of your Astro project. Defaults to the current working directory.
inlineConfig.logLevel
'debug' | 'info' | 'warn' | 'error' | 'silent'
default:"'info'"
Controls the verbosity of logging output.
inlineConfig.force
boolean
default:"false"
Force a clean sync by clearing the content layer cache before generating types.

Return Value

Returns a Promise<void> that resolves when type generation completes successfully.

What It Does

The sync() function performs the following tasks:
  1. Generates src/env.d.ts: Creates TypeScript definitions for Astro’s built-in modules
  2. Creates .astro/types.d.ts: Generates type definitions in your cache directory
  3. Generates Content Collections types: Creates the astro:content module with types for your content collections
  4. Syncs content layer: Updates the content layer cache with the latest content
  5. Generates environment types: Creates types for environment variables defined in your schema

Examples

Basic Sync

import { sync } from 'astro';

await sync({
  root: './my-project',
});

console.log('Types generated!');

Force Clean Sync

Clear the cache and regenerate all types:
import { sync } from 'astro';

await sync({
  root: './my-project',
  force: true,
});

Silent Mode

import { sync } from 'astro';

await sync({
  root: './my-project',
  logLevel: 'silent',
});

Pre-Build Hook

Run sync before building to ensure types are up-to-date:
import { sync, build } from 'astro';

async function buildWithSync() {
  console.log('Generating types...');
  await sync({ root: '.' });

  console.log('Building site...');
  await build({ root: '.' });
}

buildWithSync();

Watch Script

Create a custom watch script that regenerates types on changes:
import { sync } from 'astro';
import { watch } from 'chokidar';

const contentDir = './src/content';

const watcher = watch(contentDir, {
  persistent: true,
  ignoreInitial: true,
});

watcher.on('all', async (event, path) => {
  console.log(`${event}: ${path}`);
  console.log('Regenerating types...');

  try {
    await sync({ root: '.', logLevel: 'silent' });
    console.log('Types updated!');
  } catch (error) {
    console.error('Type generation failed:', error);
  }
});

console.log(`Watching ${contentDir} for changes...`);

CI/CD Type Check

import { sync } from 'astro';
import { exec } from 'node:child_process';
import { promisify } from 'node:util';

const execAsync = promisify(exec);

async function typeCheck() {
  try {
    // Generate types
    console.log('Generating types...');
    await sync({ root: '.' });

    // Run TypeScript compiler
    console.log('Running type check...');
    const { stdout, stderr } = await execAsync('tsc --noEmit');

    if (stderr) {
      console.error('Type errors found:');
      console.error(stderr);
      process.exit(1);
    }

    console.log('Type check passed!');
  } catch (error) {
    console.error('Type check failed:', error);
    process.exit(1);
  }
}

typeCheck();

Content Collections Sync

Ensure content collection types are generated before running tests:
import { sync } from 'astro';

// In your test setup
before(async () => {
  await sync({
    root: './test-fixtures/content-collections',
    logLevel: 'silent',
  });
});

Multiple Projects

import { sync } from 'astro';

const projects = [
  './packages/site-1',
  './packages/site-2',
  './packages/site-3',
];

async function syncAll() {
  for (const project of projects) {
    console.log(`Syncing ${project}...`);
    await sync({ root: project });
  }
  console.log('All projects synced!');
}

syncAll();

Error Handling

import { sync } from 'astro';

async function safeSync() {
  try {
    await sync({ root: './my-project' });
    console.log('Successfully generated types');
  } catch (error) {
    if (error.message.includes('content config')) {
      console.error('Content configuration error:', error.message);
    } else {
      console.error('Sync failed:', error);
    }
    process.exit(1);
  }
}

safeSync();

Development Workflow

import { sync, dev } from 'astro';

async function devWithSync() {
  // First sync to generate types
  console.log('Generating types...');
  await sync({ root: '.' });

  // Then start dev server
  console.log('Starting dev server...');
  const server = await dev({ root: '.' });

  console.log(`Dev server running at http://localhost:${server.address.port}`);
}

devWithSync();

Monorepo Setup

import { sync } from 'astro';
import { glob } from 'glob';

async function syncWorkspaces() {
  // Find all Astro projects in the monorepo
  const astroConfigs = await glob('packages/*/astro.config.{mjs,js,ts}');

  const projects = astroConfigs.map((config) =>
    config.replace(/\/astro\.config\.[^/]+$/, '')
  );

  console.log(`Found ${projects.length} Astro projects`);

  // Sync all projects in parallel
  await Promise.all(
    projects.map((project) => {
      console.log(`Syncing ${project}...`);
      return sync({ root: project, logLevel: 'silent' });
    })
  );

  console.log('All workspaces synced!');
}

syncWorkspaces();

When to Use

You should run sync() when:
  • Adding or modifying content collections
  • Adding or changing content schemas
  • Setting up a new project
  • After pulling changes that affect content
  • Before running type checks in CI/CD
  • When content collection types are out of date

Build docs developers (and LLMs) love