Zero to Nix is your guide to learning Nix and flakes. Created by Determinate Systems.
Make sure that you have Nix and direnv installed, then:
# Activate Nix development environment
direnv allow
# Recommended
alias npm=pnpm
To run the site in development mode (with live reload when you make changes):
dev
To run the site in preview mode (with a static web server and no live reload):
preview
# Alternatively
nix run
Then open your browser to http://localhost:3000.
The site has some CI checks that run in GitHub Actions, like link checking. To run the whole CI suite locally:
ci
To ensure that the site can build properly in response to changes:
build
As an alternative, you can run the whole CI suite, which also builds the site.
To ensure that everything is properly formatted:
format
The Zero to Nix site is automatically published on Vercel, which also provides deploy previews for pull requests.
Zero to Nix's "stack" 🥞:
- îles for content management and site generation
- Vue for templating
- MDX for content
- Tailwind for CSS
The site uses a number of custom MDX components to spice up the usual Markdown content.
Component | What it does |
---|---|
Admonition |
An admonition block of type danger , info , success , or warning .Adding an id makes it a stateful callout dropdown. |
Concept |
Add a hoverable tool tip for a concept |
Language |
Displays which (programming) language the user has selected |
Languages |
Provides a (programming) language selector |
NixStorePath |
Provides a colorful visualization of Nix store path components |
Shell |
Provides language- and system-specific shell commands |
SpecificLanguage |
Displays the enclosed content only if the user has selected a specific language |
System |
Displays the currently selected system (Linux vs. macOS) |
Systems |
Provides a system selector (Linux vs. macOS) |
Note: any time you use one of these components in an MDX file, you need to add a
client:load
directive to it. This is one of îles' so-called hydration directives. There are other directives available, butclient:load
is the one that we need to use, as it ensures that the component is loaded as soon as the user comes to the page.
Directory | What it contains |
---|---|
src/assets |
Assets to be processed (only CSS for now) |
src/components |
Vue components used throughout the site |
src/layouts |
Vue layouts for specific page types |
src/logic |
TypeScript helper stuff for state and content management |
src/pages |
The content of the site (all MDX) plus some Vue templates for specific pages |
public |
Assets that won't be processed (favicon, etc.) |
For quick start pages:
title
summary
(an array of things that the user will accomplish in the guide)order
(ascending)
For concept pages:
title
snippet
(a brief explanation of the concept that appears in pop-ups)related
(an array of IDs representing concept pages, likeflakes
ornix-store
)externalSources
(an array of links to external sources, such as official docs)
There are a few other important files you should be aware of when working on the site:
src/app.ts
defines global page metadatasrc/site.ts
defines site-level values, like the title, description, navbar links, and more.src/logic/content.ts
provides the content management logic for the site (type-safe page frontmatter, functions to fetch and sort documents, and more)src/logic/state.ts
defines all stateful logic using the nanostores librarysrc/logic/theme.ts
provides logic for the light/dark theme switcher
If you happen to use VS Code as your editor, we recommend adding these extensions:
Vue.volar
unifiedjs.vscode-mdx
bradlc.vscode-tailwindcss
esbenp.prettier-vscode
vscode.vscode-typescript-next
We also recommend adding these settings to your local .vscode/settings.json
:
{
"[mdx]": {
// By default, this extension overwrites our one-sentence-per-line policy
"editor.formatOnSave": false,
// This is a nice helper for longer sentences
"editor.wordWrapColumn": 100,
"editor.wordWrap": "wordWrapColumn"
},
// Format everything using the Prettier config
"editor.defaultFormatter": "esbenp.prettier-vscode",
// Keep junk out of your search results
"search.exclude": {
"**/.direnv": true,
"**/.git": true,
"**/node_modules": true,
"dist": true,
"pnpm-lock.yaml": true,
"*.d.ts": true,
"tmp": true
}
}