Design system

A design system is the set of decisions that makes an application feel coherent: color, typography, spacing, radius, elevation, motion, chart palettes, and the component styles that turn those tokens into real buttons, inputs, badges, cards, tabs, modals, tooltips, and progress indicators.
Fission supports Design System Package JSON files as a build-time input. The app does not parse JSON while it is running. Instead, a build script reads dsp.json and tokens.json, resolves the token references, and generates ordinary Rust code. Your app then chooses one of the generated themes and writes it into Env.
That keeps the hot path simple. Widgets read typed Rust values from view.env.theme; they do not search JSON, hash token names, or do string lookups while drawing a frame.

What gets generated

A DSP package contains two important files:
dsp.json, which describes the package, components, patterns, assets, and where the token file lives.
tokens.json, which contains primitive and semantic values such as colors, font sizes, spacing, radius, shadows, motion, and chart palettes.
Fission's generator turns those files into a Rust type that implements DesignSystem.
include!(concat!(env!("OUT_DIR"), "/app_design_system.rs"));

DesktopApp::new(MyApp)
    .with_design_system::<AppDesignSystem>(DesignMode::Light)
    .run()?;
AppDesignSystem is not hand-written. It is generated during cargo build, compiled into your app, and used like any other Rust type.

Add a DSP package to an app

Create a design/ folder in your app and place the package files inside it:
my-app/
  Cargo.toml
  build.rs
  design/
    dsp.json
    tokens.json
  src/
    main.rs
Once the package is in design/, generate the Rust theme from that app-local input:
use std::path::PathBuf;

fn main() {
    let manifest_dir = PathBuf::from(std::env::var("CARGO_MANIFEST_DIR").unwrap());
    let dsp_path = manifest_dir.join("design/dsp.json");

    fission_design_system_codegen::generate(fission_design_system_codegen::Config {
        dsp_path,
        out_file: "app_design_system.rs".into(),
        type_name: "AppDesignSystem".into(),
        crate_path: "fission::theme".into(),
    })
    .expect("failed to generate design system");
}
Add the generator as a build dependency:
[dependencies]
fission = { version = "0.7.0", default-features = false, features = ["desktop"] }

[build-dependencies]
fission-design-system-codegen = "0.7.0"

What you should have working

After this guide, you should be able to explain where Design system fits in the Fission lifecycle, identify the file or component you changed, run the relevant fission command, and verify the result in a real target or test.

Common mistakes to check

Symptom
What to check first
The app compiles but nothing changes
Confirm the component is actually used by the route or shell target you are running.
An action fires but state does not update
Confirm the reducer is registered with the same action value that the UI dispatches.
A platform feature reports unsupported
Confirm the target has the capability in fission.toml and the shell registered the provider.
The page works on one target but not another
Run fission doctor, then inspect target-specific configuration and feature flags.
Tests are hard to write
Split the product rule into a reducer test first, then add a UI or shell smoke test for the integration.
The generated code uses the public Fission theme API. Your application still imports Fission normally:
use fission::prelude::*;

include!(concat!(env!("OUT_DIR"), "/app_design_system.rs"));

Let the user choose light or dark

Theme choice is product state. If the user can choose light mode or dark mode, keep that choice in GlobalState, then mirror it into Env with .with_sync_env(...).
DesktopApp::new(MyApp)
    .with_design_system::<AppDesignSystem>(DesignMode::Light)
    .with_sync_env(|state: &MyState, env: &mut Env| {
        env.theme = AppDesignSystem::theme(state.theme_mode);
        env.window.title = WindowTitle::plain("My Fission App");
    })
    .run()?;
Env is the environment shared with widgets during component conversion. Putting the generated Theme there means every widget sees the same colors, typography, component sizes, shadows, and motion settings for the current frame.

What Fission consumes today

The generated theme is not just a bag of metadata. Fission resolves DSP component styles into typed runtime structs.
Buttons consume hierarchy styles such as primary, secondary_color, secondary_gray, tertiary_color, link_color, and destructive. Button sizes such as sm, md, lg, and xl map to first-class component size slots. State tables such as default, hover, active, focus, and disabled resolve into typed style values before the widget renders.
Inputs, badges, tabs, cards, modals, tooltips, and progress bars follow the same model. They read generated component styles for background fills, text colors, borders, radius, padding, font sizes, font weights, line heights, shadows, and state-specific overrides. Charts read the generated data-visualization palette from the theme instead of inventing a separate chart palette.
The important rule is that JSON stops at conversion time. Runtime code sees Rust values.

Start from a bundled system when it fits

Fission ships several bundled DSP packages for common product directions. They are not magic modes inside the renderer. Each one is a normal dsp.json and tokens.json package under crates/core/fission-theme/design, generated into a Rust DesignSystem implementation at conversion time.
Preset
Generated Rust type
Use when
Fission default
FissionDefaultDesignSystem
You want the Fission documentation and example visual language.
Material Design 3
FissionMaterialDesign3DesignSystem
You want an Android-oriented, role-based design system with Material-style color, shape, and component density.
Fluent 2
FissionFluent2DesignSystem
You want a Microsoft productivity-app feel with Fluent-style density, neutral surfaces, Segoe-style typography, and restrained radius.
Liquid Glass
FissionLiquidGlassDesignSystem
You want layered translucent surfaces, luminous tint, larger radius, and depth-forward presentation.
Cupertino
FissionCupertinoDesignSystem
You want UIKit-style iOS conventions while using the cross-platform Cupertino naming convention.
Use a preset exactly the same way you use a generated app design system:
use fission::prelude::*;
use fission::theme::{DesignMode, FissionCupertinoDesignSystem};

DesktopApp::new(MyApp)
    .with_design_system::<FissionCupertinoDesignSystem>(DesignMode::Light)
    .with_sync_env(|state: &MyState, env: &mut Env| {
        env.theme = FissionCupertinoDesignSystem::theme(state.theme_mode);
    })
    .run()?;
Presets are a good starting point, not a cage. If your product needs a slightly different brand color, radius scale, chart palette, or component state table, copy the preset package into your app's design/ folder and edit the JSON there. Your app's build script can then generate AppDesignSystem from that copy.
That keeps the same architecture: design information enters as DSP JSON at conversion time, and widgets consume typed Rust theme values at runtime.

Where to get DSP and token files

You can start from Fission's default package, export from a design tool, or use public token systems as reference material.
Adobe introduced Design System Package as an open package format for sharing design-system information across tools, including tokens, documentation, snippets, and examples.
Google's Material token repository documents Material Design DSP usage and can be used as a reference for a real DSP-style token package.
Adobe Spectrum publishes structured design-token data for colors, layout, typography, and component tokens.
Tokens Studio and Style Dictionary are useful when your team already manages design tokens in Figma or JSON and needs to transform them for engineering.
Token generators such as Tokenry can produce a first pass of primitive and semantic tokens when you are starting from a brand color instead of an existing system.
Useful links:

Example app

The repository includes examples/todo-design-system. It is intentionally small: a todo list, a text input, buttons, badges, a card surface, and a light/dark toggle.
The example's build.rs points at Fission's bundled DSP package so the example does not carry a large local copy of the JSON files. In your own app, copy the default package, replace it with your design team's package, or point the generator at a package produced by your design tooling.
Run it with:
cargo run -p todo-design-system
Fission
A cross-platform, GPU-accelerated user interface framework for Rust. MIT licensed.
Copyright (c) 2026 Fission
Ready to use today. Widget APIs are expected to remain stable; some runtime and shell APIs may change before 1.0.0.
Fission 0.7.0