···13131414> `flake-file` and [vic](https://bsky.app/profile/oeiuwq.bsky.social)'s [dendritic libs](https://vic.github.io/dendrix/Dendritic-Ecosystem.html#vics-dendritic-libraries) made for you with Love++ and AI--. If you like my work, consider [sponsoring](https://github.com/sponsors/vic)
15151616-**flake-file** lets you generate a clean, maintainable `flake.nix` from modular options. Use the _real_ Nix language to define your inputs.
1616+**flake-file** lets you generate a clean, maintainable `flake.nix` from Nix module options. Use the _real_ Nix language to define your inputs.
1717+1818+It makes your flake definition base on the Nix module system.
1919+2020+This means
17211818-It makes your flake configuration modular and based on the Nix module system. This means you can use
1919-`lib.mkDefault` or anything you normally do with Nix modules, and have them reflected in flake schema values.
2222+- You can use `lib.mkDefault` or anything you normally do with the Nix language, and have them reflected in flake.nix.
2323+- Your inputs follow a **typed Input Schema**.
2424+- Your outputs can be defined on a **typed Output Schema**.
20252126> Despite the original flake-oriented name, it NOW also works on _stable Nix_, non-flakes environments via [npins](templates/npins) or [unflake](templates/unflake).
2227···2530## Features
26312732- Flake definition aggregated from Nix modules.
2828-- Schema as [options](https://github.com/vic/flake-file/blob/main/modules/options/default.nix).
3333+- [Input](https://github.com/vic/flake-file/blob/main/modules/options/default.nix) and Output schemas based on Nix types.
2934- Syntax for nixConfig and follows is the same as in flakes.
3035- `flake check` ensures files are up to date.
3136- App for `flake.nix` generator: `nix run .#write-flake`
···44494550</td></tr></table>
46514747----
4848-4949-## Table of Contents
5050-5151-- [Who?](#who-is-this-for)
5252-- [What?](#what-is-flake-file)
5353-- [Getting Started](#getting-started-try-it-now)
5454-- [Usage](#usage)
5555-- [Available Options](#available-options)
5656-- [About the Flake `output` function](#about-the-flake-output-function)
5757-- [Automatic flake.lock flattening](#automatic-flakelock-flattening)
5858-- [Migration Guide](#migration-guide)
5959-- [Development](#development)
60526161----
6262-6363-## Who is this for?
6464-6565-- Nix users who want to keep their `flake.nix` modular and maintainable
6666-- Anyone using Nix modules and looking to automate or simplify flake input management
6767-- Teams or individuals who want to share and reuse flake modules **across projects** even if some use flakes and others npins.
6868-6969----
7070-7171-## What is flake-file?
7272-7373-flake-file lets you make your `flake.nix` dynamic and modular. Instead of maintaining a single, monolithic `flake.nix`, you define your flake inputs in separate modules _close_ to where their inputs are used. flake-file then automatically generates a clean, up-to-date `flake.nix` for you.
7474-7575-- **Keep your flake modular:** Manage flake inputs just like the rest of your Nix configuration.
7676-- **Automatic updates:** Regenerate your `flake.nix` with a single command whenever your options change.
7777-- **Flake as dependency manifest:** Use `flake.nix` only for declaring dependencies, not for complex Nix code.
7878-- **Share and reuse modules:** Teams can collaborate on and share flake modules across projects, including their dependencies.
7979-8080-> Real-world examples: [vic/vix](https://github.com/vic/vix) uses flake-file. Our [`dev/`](https://github.com/vic/flake-file/blob/main/dev) directory also uses flake-file to test this repo. [More examples on GitHub](https://github.com/search?q=%22vic%2Fflake-file%22+language%3ANix&type=code).
8181-8282----
8383-8484-## Getting Started (try it now!)
8585-8686-To get started quickly, create a new flake based on our [dendritic](https://github.com/vic/flake-file/tree/main/templates/dendritic) template:
8787-8888-```shell
8989-nix flake init -t github:vic/flake-file#dendritic
9090-nix run ".#write-flake" # regenerate flake.nix and flake.lock
9191-cat flake.nix # flake.nix built from your options
9292-nix flake check # check that flake.nix is up to date
9393-```
9494-9595-> [!TIP]
9696-> See the [Migration Guide](#migration-guide) if you're moving from an existing flake.
9797-9898----
9999-100100-## Usage
101101-102102-The following is a complete example from our [`templates/dendritic`](https://github.com/vic/flake-file/blob/main/templates/dendritic) template. It imports all modules from [`flake-file.flakeModules.dendritic`](https://github.com/vic/flake-file/tree/main/modules/dendritic).
103103-104104-```nix
105105-{ inputs, lib, ... }:
106106-{
107107- # That's it! Importing this module will add dendritic-setup inputs to your flake.
108108- imports = [ inputs.flake-file.flakeModules.dendritic ];
109109-110110- # Define flake attributes on any flake-parts module:
111111- flake-file = {
112112- description = "My Awesome Flake";
113113- inputs.nixpkgs.url = lib.mkDefault "github:NixOS/nixpkgs/nixpkgs-unstable";
114114- inputs.nixpkgs-lib.follows = "nixpkgs";
115115- };
116116-}
117117-```
118118-119119-### Available flakeModules
120120-121121-#### [`flakeModules.default`](https://github.com/vic/flake-file/tree/main/modules/default.nix)
122122-123123-- Defines `flake-file` options.
124124-- Exposes `packages.write-flake`.
125125-- Exposes flake checks for generated files.
126126-127127-#### [`flakeModules.import-tree`](https://github.com/vic/flake-file/tree/main/modules/import-tree.nix)
128128-129129-- Adds [import-tree](https://github.com/vic/import-tree)
130130-131131-#### [`lib.flakeModules.flake-parts-builder`](https://github.com/vic/flake-file/tree/main/modules/flake-parts-builder/default.nix)
132132-133133-- Includes flake-parts-builder's `_bootstrap.nix`.
134134-- Uses bootstrap to load parts from ./flake-parts
135135-- Uses bootstrap to load ./flake-parts/\_meta as flake-file configs.
136136-137137-#### [`flakeModules.allfollow`](https://github.com/vic/flake-file/tree/main/modules/prune-lock/allfollow.nix)
138138-139139-- Enables [automatic flake.lock flattening](#automatic-flakelock-flattening) using [spikespaz/allfollow](https://github.com/spikespaz/allfollow)
140140-141141-#### [`flakeModules.nix-auto-follow`](https://github.com/vic/flake-file/tree/main/modules/prune-lock/nix-auto-follow.nix)
142142-143143-- Enables [automatic flake.lock flattening](#automatic-flakelock-flattening) using [fzakaria/nix-auto-follow](https://github.com/fzakaria/nix-auto-follow)
144144-145145-#### [`flakeModules.dendritic`](https://github.com/vic/flake-file/tree/main/modules/dendritic/default.nix)
146146-147147-- Includes flakeModules.default.
148148-- Includes flakeModules.import-tree.
149149-- Enables [`flake-parts`](https://github.com/hercules-ci/flake-parts).
150150-- Sets `outputs` to `inputs: inputs.flake-parts.lib.mkFlake { inherit inputs; } (inputs.import-tree ./modules)`.
151151-152152-> Previously, this module included `flake-aspects` and `den` as dependencies. It now provides a pure flake-parts Dendritic setup. If you need the complete [den](https://github.com/vic/den) functionality, use den's `flakeModules.dendritic` instead.
153153-154154-#### [`flakeModules.npins`](https://github.com/vic/flake-file/tree/main/modules/npins.nix)
155155-156156-- Defines `flake-file` options for [npins](https://github.com/andir/npins)-based dependency pinning.
157157-- Exposes `write-npins` to generate/update the `npins/` directory from declared inputs.
158158-- Supports `github`, `gitlab`, `channel`, `tarball`, and `git` URL schemes.
159159-- Respects `follows` for transitive dependency deduplication.
160160-- Prunes stale pins automatically.
161161-- See [templates/npins](templates/npins) for usage.
162162-163163-#### [`flakeModules.unflake`](https://github.com/vic/flake-file/tree/main/modules/unflake.nix)
164164-165165-- Defines `flake-file` options.
166166-- Exposes `write-unflake` to generate `unflake.nix` or `npins`. See [templates/unflake](templates/unflake) for usage.
167167-168168-### Flake Templates
169169-170170-#### [`default`](templates/default) template
171171-172172-A more basic, explicit setup.
173173-174174-```nix
175175-# See templates/default
176176-{ inputs, ... }: {
177177- imports = [
178178- inputs.flake-file.flakeModules.default
179179- ];
180180-181181- flake-file.inputs = {
182182- flake-file.url = "github:vic/flake-file";
183183- flake-parts.url = "github:hercules-ci/flake-parts";
184184- nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
185185- };
186186-187187- systems = inputs.nixpkgs.lib.systems.flakeExposed;
188188-}
189189-```
190190-191191-> [!IMPORTANT]
192192-> Use `nix run .#write-flake` to generate.
193193-194194-> [!TIP]
195195-> You can use the `write-flake` app as part of a devshell or git hook.
196196-197197-#### [`dendritic`](templates/dendritic) template
198198-199199-A template for dendritic setups; includes `flakeModules.dendritic`.
200200-201201-#### [`parts`](templates/parts) template
202202-203203-A template that uses `lib.flakeModules.flake-parts-builder`.
204204-205205-#### [`npins`](templates/npins) template
206206-207207-Uses [npins](https://github.com/andir/npins) to pin and fetch inputs defined as options for non-flakes stable Nix environments. Supports channels, GitHub, GitLab, tarballs, and git repos. Recommended for new non-flake projects.
208208-209209-#### [`unflake`](templates/unflake) template
210210-211211-Uses [goldstein/unflake](https://codeberg.org/goldstein/unflake) to pin and fetch inputs that were defined as options for non-flakes stable Nix environments.
212212-213213----
214214-215215-## Available Options
216216-217217-Options use the same attributes as the flake schema. See below for details.
218218-219219-| Option | Description |
220220-| ------------------------------------------------- | ----------------------------------------------------------- |
221221-| `flake-file.description` | Sets the flake description |
222222-| `flake-file.nixConfig` | Flake-level `nixConfig` (typed attrset) |
223223-| `flake-file.outputs` | Literal Nix code for `outputs` function |
224224-| `flake-file.formatter` | Function: `pkgs -> program` to format generated `flake.nix` |
225225-| `flake-file.do-not-edit` | Header comment added atop generated file |
226226-| `flake-file.inputs.<name>.url` | Source URL (e.g. `github:owner/repo`) |
227227-| `flake-file.inputs.<name>.type` | Reference type (`github`, `path`, etc.) |
228228-| `flake-file.inputs.<name>.owner` | Owner (for typed VCS refs) |
229229-| `flake-file.inputs.<name>.repo` | Repo name |
230230-| `flake-file.inputs.<name>.path` | Local path reference |
231231-| `flake-file.inputs.<name>.id` | Flake registry id |
232232-| `flake-file.inputs.<name>.dir` | Subdirectory within repo/path |
233233-| `flake-file.inputs.<name>.narHash` | NAR hash pin |
234234-| `flake-file.inputs.<name>.rev` | Commit hash pin |
235235-| `flake-file.inputs.<name>.ref` | Branch or tag pin |
236236-| `flake-file.inputs.<name>.host` | Custom host for git forges |
237237-| `flake-file.inputs.<name>.submodules` | Whether to fetch git submodules |
238238-| `flake-file.inputs.<name>.flake` | Boolean: is it a flake? (default true) |
239239-| `flake-file.inputs.<name>.follows` | Follow another input's value |
240240-| `flake-file.inputs.<name>.inputs.<dep>.follows` | Nested input follow tree |
241241-| `flake-file.inputs.<name>.inputs.<dep>.inputs...` | Recursively follow deeper deps |
242242-| `flake-file.write-hooks` | List of ordered hooks (by `index`) after writing |
243243-| `flake-file.check-hooks` | List of ordered hooks (by `index`) during check |
244244-| `flake-file.prune-lock.enable` | Enable automatic flake.lock pruning |
245245-| `flake-file.prune-lock.program` | Function building pruning executable |
246246-247247-Example:
248248-249249-```nix
250250-flake-file = {
251251- description = "my awesome flake";
252252- nixConfig = {}; # attrset (free-form, typed as attrs)
253253- inputs.<name>.url = "github:foo/bar";
254254- inputs.<name>.flake = false;
255255- inputs.<name>.inputs.nixpkgs.follows = "nixpkgs";
256256-};
257257-```
258258-259259-> [!TIP]
260260-> See also, [options.nix](https://github.com/vic/flake-file/blob/main/modules/options/default.nix).
261261-262262----
263263-264264-## About the Flake `outputs` function
265265-266266-The `flake-file.outputs` option is a literal Nix expression. You cannot convert a Nix function value into a string for including in the generated flake file.
267267-268268-It defaults to:
269269-270270-```nix
271271-inputs: import ./outputs.nix inputs
272272-```
273273-274274-We recommend using this default, as it keeps your flake file focused on definitions of inputs and nixConfig. All Nix logic is moved to `outputs.nix`. Set this option only if you want to load another file with [a Nix one-liner](https://github.com/vic/flake-file/blob/main/modules/dendritic/dendritic.nix), but not for including a large Nix code string in it.
275275-276276----
277277-278278-<a name="parts_templates"></a>
279279-280280-## Add flake-parts-builder templates
281281-282282-Tired of endlessly repeating tiny flake-parts modules or copy-pasting
283283-snippets between your projects? No more!
284284-285285-[flake-parts-builder](https://github.com/tsandrini/flake-parts-builder)
286286-lets you _incrementally_ add templated parts.
287287-This is much better than normal flake templates, since flake-parts templates
288288-can be added or removed at any time, not only at project initialization.
289289-290290-```nix
291291-{ inputs, ... }: {
292292- imports = [
293293- (inputs.flake-file.lib.flakeModules.flake-parts-builder ./flake-parts)
294294- ];
295295-}
296296-```
297297-298298-> [!IMPORTANT]
299299-> Use `github:vic/flake-parts-builder/write-meta` until [flake-parts-builder#60](https://github.com/tsandrini/flake-parts-builder/pull/60) gets merged. This branch will also write each parts meta.nix file, so it can be used by flake-file to manage your flake.nix.
300300-301301-> [!WARNING]
302302-> Only use `flake-parts-builder add` subcommand, since `init` will _overwrite_ the flake.nix file that is already being managed by flake-file.
303303-304304-```shell
305305-nix run github:vic/flake-parts-builder/write-meta -- add --write-meta --parts systems,treefmt $PWD
306306-```
307307-308308-## Hooks for write-flake and checks
309309-310310-You can add custom commands to be run whenever your flake.nix has been
311311-written or checked.
312312-313313-> [!TIP]
314314-> See `flake-file.write-hooks` and `flake-file.check-hooks` options.
315315-316316-## Automatic flake.lock flattening
317317-318318-You can use the `prune-lock` [options](https://github.com/vic/flake-file/blob/main/modules/options/prune-lock.nix)
319319-to specify a command that `flake-file` will use whenever your flake.nix file is generated
320320-to flatten your flake.lock dependency tree.
321321-322322-For flattening mechanisms we provide:
323323-324324-- [`flakeModules.allfollow`](https://github.com/vic/flake-file/blob/main/modules/prune-lock/allfollow.nix) that enables this using [`spikespaz/allfollow`](https://github.com/spikespaz/allfollow)
325325-- [`flakeModules.nix-auto-follow`](https://github.com/vic/flake-file/blob/main/modules/prune-lock/nix-auto-follow.nix) that enables this using [`fzakaria/nix-auto-follow`](https://github.com/fzakaria/nix-auto-follow)
326326-327327-```nix
328328-{ inputs, ... }:
329329-{
330330- imports = [
331331- inputs.flake-file.flakeModules.nix-auto-follow
332332- # or optionally
333333- # inputs.flake-file.flakeModules.allfollow
334334- ];
335335-}
336336-```
337337-338338----
339339-340340-## Migration Guide
341341-342342-This section outlines the recommended steps for adopting `flake-file` in your own repository.
343343-344344-1. **Prerequisite:** Ensure you have already adopted [flake-parts](https://flake.parts).
345345-346346-1. **Add Inputs:** In your current `flake.nix`, add the following input:
347347-348348- ```nix
349349- flake-file.url = "github:vic/flake-file";
350350- ```
351351-352352-1. **Move Outputs:** Copy the contents of your `outputs` function into a file `./outputs.nix`:
353353-354354- ```nix
355355- # outputs.nix -- this is the contents of your `outputs` function from the original flake.nix file.
356356- inputs: inputs.flake-parts.lib.mkFlake { inherit inputs; } {
357357- imports = [
358358- ./modules/inputs.nix # Add this for step 4.
359359- # Feel free to split ./modules/inputs.nix into other modules as you see fit.
360360- # If you end having lots of modules, consider using import-tree for auto importing them.
361361- ];
362362- }
363363- ```
364364-365365-1. **Move Inputs:** Copy your current flake.nix file as a flake-parts module (e.g., `modules/inputs.nix`):
366366-367367-> [!IMPORTANT]
368368-> Make sure you `git add` so that new files are visible to Nix.
369369-370370-```nix
371371-# modules/inputs.nix
372372-{ inputs, ... }:
373373-{
374374- imports = [
375375- inputs.flake-file.flakeModules.default # flake-file options.
376376- ];
377377- flake-file = {
378378- inputs = {
379379- flake-file.url = "github:vic/flake-file";
380380- # ... all your other original flake inputs here.
381381- };
382382- nixConfig = { }; # if you had any.
383383- description = "Your flake description";
384384- };
385385-}
386386-```
387387-388388-5. **Backup:** Back up your flake.nix into flake.nix.bak before regenerating it.
389389-1. **Generate:** Execute `nix run .#write-flake` to generate flake.nix.
390390-1. **Verify:** Check flake.nix and if everything is okay, remove the backup file.
391391-392392-You are done! Now you can split dependencies from `modules/inputs.nix` into other flake-part modules as you see fit:
393393-394394-```nix
395395-# ./modules/<name>.nix -- Replace `<name>` with some dependency.
396396-{ inputs, lib, ... }: {
397397- flake-file.inputs.<name>.url = ...;
398398-399399- # Example usage: include the flakeModule once it has been added to flake.nix.
400400- imports = lib.optionals (inputs ? <name>) [ inputs.<name>.flakeModule ];
401401-}
402402-```
403403-404404----
405405-406406-## Bootstrapping
407407-408408-You can generate `flake.nix`, `inputs.nix`, `unflake.nix` or `npins` by using the following command:
409409-410410-```shell
411411-# create a bootstrap module. add any dependencies you want
412412-echo '{ flake-file.inputs.flake-file.url = "github:vic/flake-file"; }' > bootstrap.nix # filename is not important
413413-414414-# replace write-flake with: write-inputs / write-unflake / write-npins
415415-nix-shell https://github.com/vic/flake-file/archive/refs/heads/main.zip -A flake-file.sh --run write-flake --arg modules ./bootstrap.nix
416416-```
417417-418418-`bootstrap.nix` can also be a `./modules` directory that will be auto-imported using import-tree.
419419-420420-## Development
421421-422422-Use `nix develop ./dev` or with direnv: `use flake ./dev`.
423423-424424-```shell
425425-[[general commands]]
426426-427427- check - run flake check
428428- fmt - format all files in repo
429429- menu - prints this menu
430430- regen - regenerate all flake.nix files in this repo
431431-```
432432-433433----
434434-435435-## Contributing & Support
436436-437437-- Found a bug or have a feature request? [Open an issue](https://github.com/vic/flake-file/issues).
438438-- Contributions are welcome!
439439-440440----
441441-442442-Made with \<3 by [@vic](https://x.com/oeiuwq)
5353+## Learn more: [Documentation](https://flake-file.oeiuwq.com)