dotstate 0.3.4

A modern, secure, and user-friendly dotfile manager built with Rust
Documentation
---
import Layout from '../layouts/Layout.astro';
import TopNav from '../components/TopNav.astro';
import InstallBar from '../components/InstallBar.astro';
import TuiPreview from '../components/TuiPreview.astro';

const features = [
    { i: '◐', t: 'Profiles', d: 'Separate sets of files for work, personal, servers, or any context you care about.' },
    { i: '⧉', t: 'Inheritance', d: "A child profile extends a parent and only overrides what's different. Changes flow down." },
    { i: '▦', t: 'Packages', d: 'Track CLI tools per profile. Works with brew, cargo, npm, pip, or any custom script.' },
    { i: '◯', t: 'Safe by design', d: 'Automatic backups before every operation. No shell injection. Validated paths.' },
];

const steps = [
    { t: 'Install', d: 'One line in your terminal. A single binary lands in your path; nothing else changes.' },
    { t: 'Connect a repo', d: 'Let dotstate create one on GitHub, or point it at any existing git repository you already own.' },
    { t: 'Adopt dotfiles', d: 'Pick files from your home directory in the TUI. Originals are backed up before anything moves.' },
    { t: 'Sync & switch', d: 'One command to push and pull. Switch profiles to reshape your environment on the fly.' },
];

const cliGroups = [
    {
        title: 'Files',
        rows: [
            ['dotstate', 'Open the interactive TUI'],
            ['dotstate list', 'List every synced file in the active profile'],
            ['dotstate add ~/.myconfig', 'Adopt a file into the active profile'],
            ['dotstate activate', 'Re-create symlinks (useful after cloning on a new machine)'],
            ['dotstate deactivate', 'Restore original files and remove symlinks'],
        ],
    },
    {
        title: 'Sync',
        rows: [
            ['dotstate sync', 'Commit, pull, and push in one step'],
            ['dotstate sync -m "message"', 'Sync with a custom commit message'],
            ['dotstate upgrade', 'Check for, and optionally install, updates'],
        ],
    },
    {
        title: 'Packages',
        rows: [
            ['dotstate packages list', 'Show tracked packages and their installation state'],
            ['dotstate packages add -n ripgrep -m brew -b rg', 'Track a new package for this profile'],
            ['dotstate packages check', "Check what's missing on this machine"],
            ['dotstate packages install', 'Install every missing package'],
        ],
    },
    {
        title: 'Shell',
        rows: [
            ['dotstate completions zsh', 'Emit zsh completions (also: bash, fish)'],
            ['dotstate help', 'Full command reference'],
        ],
    },
];
---

<Layout>
    <TopNav active={null} context="landing" />

    <section class="linen-hero">
        <div class="linen-hero-top">
            <h1 class="linen-h1 reveal">
                <span class="quiet">A calmer home</span><br />
                for the <span class="moss">files</span> that<br />
                configure <span class="quiet">everything.</span>
            </h1>
            <p class="linen-lead reveal delay-1">
                <b>dotstate</b> is a dotfile manager for people who'd rather stop thinking about dotfiles.
                It keeps your shell, editor, and terminal configs synced across every machine — through profiles,
                inheritance, and one command to sync.
            </p>
        </div>

        <InstallBar />
    </section>

    <section class="linen-tui-section">
        <div class="linen-tui-head reveal">
            <div>
                <div class="k">The interface</div>
                <h2>Quiet, <span class="moss">by design.</span></h2>
            </div>
            <p>
                A restrained TUI with mouse support, keyboard shortcuts, and eleven themes — from this soft light palette
                to Tokyo Night, Gruvbox, and Catppuccin.
            </p>
        </div>
        <TuiPreview />
    </section>

    <section class="linen-features">
        <div class="linen-feat-grid">
            {features.map((f, i) => (
                <div class={`linen-feat reveal delay-${(i % 3) + 1}`}>
                    <div class="ico">{f.i}</div>
                    <h3>{f.t}</h3>
                    <p>{f.d}</p>
                </div>
            ))}
        </div>
    </section>

    <section class="linen-section" id="how">
        <div class="linen-sec-head reveal">
            <div>
                <div class="num">SECTION 01</div>
                <h2>Four steps, <span class="moss">then it's quiet.</span></h2>
            </div>
            <div>
                <p>
                    Setup is a single evening — sometimes less. Afterwards, dotstate sits in the background and only
                    asks for your attention when you want it to.
                </p>
                <a class="linen-deep" href="/install">Read the full install guide →</a>
            </div>
        </div>
        <div class="linen-steps">
            {steps.map((s, i) => (
                <div class={`linen-step reveal delay-${(i % 3) + 1}`}>
                    <div class="nrow">
                        <span>STEP {String(i + 1).padStart(2, '0')}</span>
                        <span class="pip">
                            {[0, 1, 2, 3].map((j) => <span class={j <= i ? 'on' : ''}></span>)}
                        </span>
                    </div>
                    <div>
                        <h3>{s.t}</h3>
                        <p>{s.d}</p>
                    </div>
                </div>
            ))}
        </div>
    </section>

    <section class="linen-section" id="cli">
        <div class="linen-sec-head reveal">
            <div>
                <div class="num">SECTION 02</div>
                <h2>The <span class="moss">command line</span>,<br />for when the TUI isn't enough.</h2>
            </div>
            <div>
                <p>
                    Everything the interactive TUI can do, dotstate can do as a script. Good for CI, bootstrapping a new
                    machine, or staying on the home row.
                </p>
                <a class="linen-deep" href="/profiles">Learn about profiles &amp; inheritance →</a>
            </div>
        </div>
        <div class="linen-cli reveal">
            {cliGroups.map((grp) => (
                <div class="linen-cli-group">
                    <h4>{grp.title}</h4>
                    {grp.rows.map(([c, d]) => (
                        <div class="linen-cli-row">
                            <code>{c}</code>
                            <div class="desc">{d}</div>
                        </div>
                    ))}
                </div>
            ))}
        </div>
    </section>

    <footer class="linen-foot" id="gh">
        <div class="linen-foot-top">
            <div>
                <p class="mark-big">dotstate</p>
                <p>Bring order to the files that quietly shape your workday. Open source, MIT-licensed, and built with Rust.</p>
                <a class="linen-badge" href="https://terminaltrove.com/dotstate/" target="_blank" rel="noopener noreferrer" title="This tool is Tool of The Week on Terminal Trove, The $HOME of all things in the terminal">
                    <span class="leaf"></span> Terminal Trove · Tool of the Week
                </a>
            </div>
            <div>
                <h4>Project</h4>
                <a href="https://github.com/serkanyersen/dotstate" target="_blank" rel="noopener noreferrer">GitHub</a>
                <a href="/changelog">Changelog</a>
                <a href="https://github.com/serkanyersen/dotstate/blob/main/CONTRIBUTING.md" target="_blank" rel="noopener noreferrer">Contributing</a>
                <a href="https://github.com/serkanyersen/dotstate/blob/main/SECURITY.md" target="_blank" rel="noopener noreferrer">Security policy</a>
            </div>
            <div>
                <h4>Documentation</h4>
                <a href="/install">Installation guide</a>
                <a href="/quickstart">Quick start</a>
                <a href="/profiles">Profiles &amp; inheritance</a>
                <a href="/packages">Package management</a>
                <a href="/themes">Themes</a>
                <a href="/keymaps">Keymaps</a>
                <a href="/cli">CLI reference</a>
            </div>
            <div>
                <h4>Community</h4>
                <a href="https://github.com/serkanyersen/dotstate/discussions" target="_blank" rel="noopener noreferrer">Discussions</a>
                <a href="https://github.com/serkanyersen/dotstate/issues" target="_blank" rel="noopener noreferrer">Issues</a>
                <a href="https://github.com/serkanyersen/dotstate/blob/main/CONTRIBUTING.md" target="_blank" rel="noopener noreferrer">Contributing</a>
                <a href="https://github.com/serkanyersen/dotstate/blob/main/CODE_OF_CONDUCT.md" target="_blank" rel="noopener noreferrer">Code of Conduct</a>
            </div>
        </div>
        <div class="linen-foot-bot">
            <span>MIT · SERKAN YERSEN · 2026</span>
            <span>BUILT WITH RATATUI, GIT2, CLAP</span>
        </div>
    </footer>
</Layout>