Getting Started with Taildown

From zero to beautiful documents in 5 minutes


Start Writing

Browser Editor

Open the editor, replace the sample with your own document, and use Export HTML to save the compiled page. No installation is required.

For offline authoring, choose Offline editor in the toolbar and save the complete editor HTML file. Open that file locally to write and render diagrams without a connection. The hosted editor loads its diagram engine on first use to keep ordinary documents faster to open; exported diagram pages still include everything they need.

The editor keeps a browser recovery copy of your draft when storage is available. If browser settings or a full quota prevent recovery, a notice appears and editing still works. Use Save or Download to keep a file copy; browser recovery is not a substitute for one.

When compilation notices appear, expand the notice list to read them. Select a reported line and column to move the editor cursor to that source location. Inline attribute notices point to the affected heading, paragraph, or link.

To print or save a PDF, open the exported HTML in your browser and choose Print. The print layout shows every tab panel, accordion answer, details section, and carousel slide; paused scroll animations are made visible. Long code wraps, controls are hidden, and the page uses dark text on white paper. Details panels return to their previous open/closed state afterward. Print the exported document rather than the editor interface; modal overlays and tooltips are not included.

Open the Live Editor

Use Save to keep the editable Taildown source as well as your exported HTML.

Use Insert or Ctrl+K (Cmd+K on Mac) to search component and formatting commands. Search by name or description, use the arrow keys to choose, then press Enter to insert at your selection. Escape cancels without changing your source. Components without a prepared example insert an empty block for you to fill using the component reference. Link formatting uses Ctrl/Cmd+Shift+K.

Cards, alerts, callouts, tabs, accordions, details, statistics, steps, definitions, carousels, timelines, avatars, breadcrumbs, pagination, sidebars, skeletons, and footnotes include editable starter examples. Try Tabs to get two populated panels, Steps for a three-stage process, Carousel for three navigable slides, or Timeline for completed, current, and upcoming milestones. These examples work offline and can be restyled with the same attributes as any other Taildown source.


Your First Document

Create a file named my-first-document.td:

# Hello World {huge-bold center primary}

Welcome to Taildown! {large muted center}

:::card {light-glass slide-up}
## Your First Card {bold}

This is a card with glassmorphism and a slide-up animation!

- :icon[check]{success} Beautiful by default
- :icon[check]{success} No configuration needed
- :icon[check]{success} Dark mode included

[Learn More](#){button primary}
:::

Compile Your Document

Basic Compilation

pnpm taildown compile my-first-document.td

This creates:

Separate CSS File

pnpm taildown compile my-first-document.td --separate

This creates:

Custom Output

pnpm taildown compile my-first-document.td --separate -o output/index.html --css output/styles.css

Understanding the Output

HTML Output

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <style>/* CSS here */</style>
</head>
<body>
  <!-- Your content -->
  <script>/* JS here */</script>
</body>
</html>

CSS Output

:root {
  --primary: #3b82f6;
  --background: #ffffff;
}

.dark {
  --background: #030712;
}

Basic Syntax Overview

Plain English Styling

Use natural language for styling:

# Large Bold Primary Heading {huge-bold primary center}

This paragraph has muted text and relaxed line spacing. {large muted relaxed-lines}

[Click Me](#){button primary large hover-lift}

Common shorthands:


Dark Mode Guide

Dark Mode is Automatic

Every Taildown document includes dark mode by default:

Features:

How it works:

  1. First Visit: Detects system dark mode preference (prefers-color-scheme)
  2. Toggle: Click the moon/sun button to switch themes
  3. Persistence: Your choice is saved to localStorage
  4. Consistency: Same theme on all future visits

CSS Variables:

:root {
  --background: #ffffff;
  --foreground: #111827;
  --primary: #3b82f6;
}

.dark {
  --background: #030712;
  --foreground: #f9fafb;
  --primary: #3b82f6;
}

All components automatically adapt to dark mode!


Project configuration in the CLI

The CLI searches its current working directory for taildown.config.js, .mjs, or .cjs (also .taildownrc.js / .mjs). Use JavaScript configuration files you trust: loading them executes their module code.

// taildown.config.mjs
export default {
  theme: {
    colors: { primary: { DEFAULT: '#86bba1', 600: '#25644a', 400: '#86efac' } },
    fonts: { serif: 'Georgia, serif' }
  },
  output: { minify: true, inlineStyles: false }
};
node packages/cli/dist/cli.js compile notes.td
node packages/cli/dist/cli.js compile notes.td --inline --no-minify
node packages/cli/dist/cli.js compile notes.td --config alternate.mjs
node packages/cli/dist/cli.js compile notes.td --no-config

An explicit configuration path resolves against the working directory. Command-line flags override configuration: --inline embeds CSS/JS, --separate writes companion assets, and --minify / --no-minify control minification. Without an explicit output.inlineStyles setting, the CLI keeps its default single-file output. output.darkMode: false or theme.darkMode.enabled: false disables the generated theme switcher.

Palette, font, component preset, minification, asset-layout, and dark-mode enablement settings are connected. Glass, animation, dark-mode method/transition, plugin, and source-map settings are not yet connected to the CLI; non-default values produce an error. Invalid configuration and conflicting output paths stop the build before existing exports or the configuration file are overwritten.

Customizing your design

The examples below use the compiler API. You can also copy their theme, styleMappings, components, and componentConfig objects into the browser editor's Design settings JSON. Include only those design objects, without JavaScript declarations or compiler output flags. See the editor design settings guide for import, export, and recovery details. Settings apply across documents in this browser workspace; save a separate settings JSON alongside your .td source to reproduce the design elsewhere.

Custom shorthands in the compiler API

When using @taildown/compiler programmatically, pass styleMappings to give a document its own vocabulary. Values are whitespace-separated style tokens; mappings expand once before normal style resolution. They can replace a built-in shorthand for that compilation, and do not change other documents or literal code examples.

import { compile } from '@taildown/compiler';

const result = await compile('# A quieter heading {editorial}', {
  inlineStyles: true,
  inlineScripts: true,
  styleMappings: {
    editorial: 'text-4xl font-semibold text-primary-600'
  }
});

In the browser editor, open Design settings from Command-K, add the same styleMappings object to the JSON, then choose Apply settings. Custom aliases become available in attribute completion and apply to previews and exports. The plain-English reference lists the built-in vocabulary.

Custom components

Define reusable containers with components. Each key must match its definition's name; choose a new name instead of replacing a registered component. htmlElement defaults to div, and defaultClasses contains CSS utility names. Normal Taildown attributes can override those defaults. Definitions belong to the compilation and never change other documents.

import { compile, getAuthoringReference } from '@taildown/compiler';

const options = {
  inlineStyles: true,
  inlineScripts: true,
  components: {
    editorial: {
      name: 'editorial',
      htmlElement: 'article',
      defaultClasses: ['p-8', 'rounded-lg', 'text-lg']
    }
  }
};

const result = await compile(
  ':::editorial\n## A considered idea\n\nYour content here.\n:::',
  options
);
const reference = await getAuthoringReference(options);

The generated HTML includes the component's markup and styling. Keep the definitions alongside the .td source for recompilation. Custom names also work in inline style attributes, such as # Title {editorial small}, where they apply classes while preserving the original Markdown element.

Authoring integrations can pass the same options to getAuthoringReference to receive custom component names, insertable examples, and custom style names. In the browser editor, add the components object to Design settings and apply it. Custom components then appear in the Command-K insertion menu and attribute completion. These definitions provide presentation and semantic containers; JavaScript behaviors remain those of the built-in components nested inside them.

Component presets

Use componentConfig to give registered or custom components document-specific defaults, variants, and sizes. Additional default classes preserve the component's structure; a named variant or size replaces that name's class list. Explicit attributes still override defaults in source order.

const componentConfig = {
  card: {
    defaultVariant: 'editorial',
    defaultSize: 'roomy',
    variants: { editorial: { classes: ['font-serif', 'border'] } },
    sizes: { roomy: { classes: ['p-8'] } }
  }
};
const result = await compile(':::card\nYour idea\n:::', { componentConfig });
const reference = await getAuthoringReference({ componentConfig });

Both calls use the same definitions. The reference includes editorial and roomy for attribute completion; other documents retain their defaults. Unknown component names and missing default variants or sizes produce errors. In a CLI configuration file, put this object under components. In the browser editor, use componentConfig in Design settings, then choose Apply settings; configured variants and sizes become available in attribute completion.

A document's palette and fonts

Pass theme.colors and theme.fonts to compile() to give a document its own palette and font stacks. These values merge with defaults and stay local to that compilation. Fonts must already be available to the browser; a font stack does not download or embed a font file.

const result = await compile('# Field notes {serif primary}', {
  inlineStyles: true,
  inlineScripts: true,
  theme: {
    colors: { primary: { DEFAULT: '#86bba1', 600: '#25644a', 700: '#184832' } },
    fonts: { sans: 'Verdana, sans-serif', serif: 'Georgia, serif', mono: 'Consolas, monospace' }
  }
});

Use {sans}, {serif}, or {mono} to choose a font family for a block. The editor offers these in style completion and the Insert / Ctrl/Cmd+K menu. Numbered palette utilities such as text-primary-600, their hover states, and responsive forms use the same document palette. Semantic text uses readable palette shades: light-mode primary text uses 600 and dark-mode primary text uses 400; override those shades when designing both themes.

Node applications can load a configuration with loadConfig from @taildown/compiler/config, then pass {theme: {colors: config.theme.colors, fonts: config.theme.fonts}} to compile(). The API's theme option covers colors and fonts. The CLI applies these through project configuration as described above; the browser editor accepts the same theme object in Design settings. Its typography buttons prepare Modern, Editorial, or Technical font choices; Apply settings activates the prepared design.

Next Steps

Syntax Guide

Deep dive into Taildown syntax and capabilities.

Read Guide

Plain English

Complete reference of all styling shorthands.

View Reference

Components

Explore the built-in component reference.

Browse Components


You're ready to start! Create your first document and see the magic happen. Remember, dark mode works automatically - just try clicking the toggle button!

Back to Home