Skip to content

Conversation

@roberth
Copy link
Member

@roberth roberth commented Dec 8, 2025

TODO:

Rendered

@roberth roberth mentioned this pull request Dec 8, 2025
@roberth roberth changed the title [RFC 0194] init: Flake Entrypoint [RFC 0194] Flake Entrypoint Dec 8, 2025
Copy link
Contributor

@iFreilicht iFreilicht left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is a great idea, though to me there seems to be an opportunity to actually simplify how flakes are presented to users. I've outlined my thoughts in two comments on the relevant sections. Discussion should probably only happen on one of them to make it easier to trace.

Comment on lines +48 to +72
The function receives:

```nix
{
# The resolved and invoked/dependency-injected flake inputs
inputs,
# The parsed flake metadata (currently from flake.nix)
flakeMeta,
# The invoked/dependency-injected *result*
self,
# The base directory of the flake
flakeDir,
# The sourceInfo, where `sourceInfo.outPath` may be `flakeDir` or any
# parent of it (if applicable; subdirectory flakes)
sourceInfo,
# ... is mandatory for forward compatibility
...
}:
# Returns standard flake outputs
{
packages = { ... };
apps = { ... };
# etc.
}
```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't it be possible to make this the format for flake.nix as well if #193 was accepted?

This would only require a small addition to the default entrypoint; after reading flake.nix, it has to check whether the expression inside it is a thunk or an attrset. If it's the latter, it evaluates the flake like it does right now. If it's the former, it will call the function the same way it would call an entrypoint defined via inputs.entrypoint.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean for the use case of defining the implementation of an entrypoint to be used elsewhere?
Then I don't think it needs to be called flake.nix and that is somewhat more rare anyway.

Alternatively, if you mean for consuming an entrypoint, you would typically have something more framework-specific or domain-specific, and then flake.nix is probably not the best name for it.

So I think what you're proposing is to make this a second format that the default built-in entrypoint understands.
On top of what you describe this then has the benefit that these flakes are not bound by the problematic outputs interface, which has no forward compatibility for new information to be passed, except through pseudo-inputs or stolen names. (These args are a record, not a dict)

## Adds conceptual complexity

Users need to understand another mechanism beyond the basic `outputs` function,
increasing the learning curve for newcomers to Nix flakes.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would not be the case if the default shape of a flake was just to be a nix function. In fact, most people wouldn't even need to know about inputs.entrypoint. It would be an extension mechanism, but not a necessity.

In fact, the learning curve might even be flattened; a flake.nix file would just contain a function like most other .nix-files already do! You could even call it with other arguments and see how it behaves. The only thing that most users would have to understand about flakes over regular nix files is that their inputs are tracked and locked by flake.toml and flake.lock (again, presuming #193 would be accepted).


- What outcomes result from a prototype of this feature?
- How should errors be reported when an entrypoint fails?
- Should there be a standard way for entrypoints to declare what files they read?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this should be part of the first iteration. There might be some UX benefits to this, but I think initially, entrypoints should handle errors and error messages themselves.

[unresolved]: #unresolved-questions

- What outcomes result from a prototype of this feature?
- How should errors be reported when an entrypoint fails?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A simple message entrypoint "flake-parts" failed with the above error.`, preceded by an error trace, seems like a workable solution.

# Unresolved questions
[unresolved]: #unresolved-questions

- What outcomes result from a prototype of this feature?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An implementation in nix gated by an experimental-feature? That seems like a good start.

# Summary
[summary]: #summary

Reduce boilerplate in flakes by changing how Nix acquires flake outputs,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So the vision is to use a project like naersk or pyproject2nix with either modifications or a wrapper flake that provides callFlakeEntrypoint and if the stars align you only need the flake.toml?

Makes TOML for RFC 193 more appealing to me.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally, yes!
To be realistic, most lang2nix still need some configuration and some hints here or there, and Nix is a pretty good language for that.
But on the other hand, those could be read from a more practical file, whether that's:

  • a couple of lines of free-form configuration in flake.toml
  • .nix files in standardized places

Both strike me as good, and it points a point on the horizon for frameworks to work towards, towards reducing configuration without purpose. I'd rather work towards an achievable goal than one that's never quite 100% solvable because of an external factor like a required flake.nix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants