Home Documentation Templates Examples Showcase GitHub ↗
Theme

Start simple · Core philosophy

You can build a lot with three primitives.

You do not need to learn all of Nift before building with it. Start with @content, @input(...) and @pathto(...). Those three ideas are enough to build serious multi-page sites with reusable structure, checked links and dependency-aware incremental rebuilds.

This is the recommended starting point.

Learn three things, build the site you actually want, and only reach for metadata, JSON, loops, conditions or explicit dependencies when a real problem asks for them.

The entire starting vocabulary

@content

Put the tracked page's content at this point in its template.

@input(...)

Parse and insert another file, while automatically recording that dependency.

@pathto(...)

Create a checked, project-aware path to a tracked output or concrete project file.

A complete page template

<!doctype html>
<html lang="en">
<head>
    @input('partials/head.html')
</head>
<body>
    @input('partials/header.html')

    <main>
        @content
    </main>

    @input('partials/footer.html')
</body>
</html>

That is already a reusable site architecture. Every tracked page can use the same shell while keeping its actual page content in a separate file.

Partials can compose other partials

templates/
├── template.html
└── partials/
    ├── head.html
    ├── header.html
    ├── navigation.html
    └── footer.html
<!-- partials/header.html -->
<header class="site-header">
    <a href="@pathto('/')">My site</a>

    @input('navigation.html')
</header>
<!-- partials/navigation.html -->
<nav>
    <a href="@pathto('/')">Home</a>
    <a href="@pathto('about')">About</a>
    <a href="@pathto('docs')">Docs</a>
</nav>

The header depends on the navigation partial. Every page that uses the header therefore depends on the navigation too. Nift discovers that relationship from normal composition; you did not have to maintain a separate dependency graph.

The dependency graph falls out of the markup

docs/getting-started
        │
        ├── content/docs/getting-started.html
        │
        └── templates/docs.html
                 │
                 ├── partials/head.html
                 ├── partials/header.html
                 │        │
                 │        └── partials/navigation.html
                 ├── partials/docs-sidebar.html
                 └── partials/footer.html

Change only the page content and Nift can rebuild that page. Change the shared navigation and Nift can identify every output that reached it through @input. Composition and incremental-build information are the same structure.

@pathto removes directory-depth bookkeeping

A shared navigation partial may be rendered into:

public/index.html
public/about.html
public/docs/index.html
public/docs/guides/install/index.html

The partial should not need four different versions of:

../../../assets/site.css

Instead it can say what it means:

<link
    rel="stylesheet"
    href="@pathto('public/assets/site.css')">

<a href="@pathto('docs/getting-started')">
    Getting started
</a>

Nift resolves the correct relative path for the output currently being generated and checks that concrete project paths exist.

This scales further than it first appears

With only these three primitives you can already build:

Project needThree-primitive solution
Shared header/footer@input partials from the page template.
Section-specific layoutsTrack different pages with different templates.
Nested reusable componentsLet input files contain more @input calls.
Navigation between generated pagesUse tracked names with @pathto.
CSS, JS, images and downloadsKeep ordinary files in public/ and reference them with @pathto.
Large sitesLet the automatically discovered dependency graph drive incremental rebuilds.
Frontend applicationsGenerate the HTML shell with Nift; let normal JS/TS/React/Vue/Svelte own browser behaviour.

You do not need a Nift abstraction for everything

If a page needs JavaScript, write JavaScript. If it needs TypeScript, compile TypeScript. If it talks to a Go API, let the Go API be a Go API. Nift's three core primitives are useful precisely because they do not force the rest of the project into a Nift-specific universe.

Start with composition. Add language features only when the content itself becomes data-driven.

When should you learn more?

Usually when you can name the problem first:

Need page metadata?

Learn $[...].

Need structured shared data?

Learn @json(...).

Need to repeat structured data?

Learn @for(...){...}.

Need conditional structured output?

Learn @if(...){...}.

Need an invisible dependency?

Learn @dep(...) or *.deps.json.

Need checked project-wide values?

Learn Project contracts.

Need anything else?

First ask whether an ordinary web/ecosystem tool already owns the problem better.

A good first Nift project can stay this small forever

There is no graduation requirement. A project that only ever uses @content, @input and @pathto is not using “beginner Nift”. It is using the central architecture directly.