How to manage design systems

Create, update, and apply design systems to screens programmatically with the SDK.

A design system defines the visual rules for your project — colors, typography, spacing. When you apply one to screens, every screen follows the same visual language. The SDK lets you create, update, and apply design systems without touching the Stitch UI.

Create a design system

import { stitch } from "@google/stitch-sdk";

const project = stitch.project("your-project-id");
const ds = await project.createDesignSystem({ displayName: "My Theme" });
console.log(`Created: ${ds.id}`);

The displayName is what appears in the Stitch UI. Pick something descriptive — “Brand Dark Mode” beats “DS 1”.

List existing design systems

const systems = await project.listDesignSystems();
for (const ds of systems) {
  console.log(`${ds.id}: ${ds.data?.displayName}`);
}

Reference a design system by ID

If you already know the asset ID, skip the network call:

const ds = project.designSystem("existing-asset-id");

This creates a handle without fetching anything from the server. Use it when you know the ID from a previous step or from the Stitch UI.

Create from a DESIGN.md

Already have a DESIGN.md defining your visual identity? Upload it and convert it into a design system in two calls:

import { readFileSync } from "node:fs";

const markdown = readFileSync("DESIGN.md", "utf-8");
const instance = await project.uploadDesignMd(Buffer.from(markdown, "utf-8").toString("base64"));
const ds = await project.createDesignSystemFromDesignMd(
  { id: instance.id, sourceScreen: instance.sourceScreen },
  "DESKTOP",
);

For the full walkthrough — including how to apply the result and use callTool directly — see How to create design systems from DESIGN.md.

Update a design system

const updated = await ds.update({ displayName: "Updated Theme" });

Apply to screens

Applying a design system re-renders screens with the new visual tokens. You need SelectedScreenInstance objects — get these from the project’s screen instances:

const projectData = await stitch.callTool("get_project", {
  name: `projects/${project.id}`,
});

// Extract screen instances
const instances = projectData.screenInstances.map((si: any) => ({
  id: si.id,
  sourceScreen: si.sourceScreen,
}));

// Apply the design system to all screens
const screens = await ds.apply(instances);
console.log(`Applied to ${screens.length} screens`);

Only include id and sourceScreen in the instance objects. Extra fields like position or dimensions cause an “invalid argument” error.

Full workflow: create and apply

Here’s the end-to-end pattern — create a project, generate screens, create a design system, and apply it:

import { stitch } from "@google/stitch-sdk";

const project = await stitch.createProject("Themed App");

// Generate a few screens
const home = await project.generate("A landing page for a productivity app");
const settings = await project.generate("A settings page with dark theme toggle");

// Create and apply a design system
const ds = await project.createDesignSystem({ displayName: "Productivity Theme" });

// Get screen instances for applying
const projectData = await stitch.callTool("get_project", {
  name: `projects/${project.id}`,
});

const instances = projectData.screenInstances.map((si: any) => ({
  id: si.id,
  sourceScreen: si.sourceScreen,
}));

await ds.apply(instances);
console.log("Design system applied to all screens");

Original: https://stitch.withgoogle.com/docs/sdk/design-systems/

Translated from the official Google Stitch documentation. Original content © Google LLC. This is an independent, unofficial translation.