[Typst packages]: Leverage the typst packages bundled into `nixpkgs`
I am new to nix and I am not yet familiar with all the conventions and best practices.
I have wondered why you are exposing the api to declare packages needed for a typst compilation using the unstable_typstPackages attribute. In my mind, letting the user provide the packages by referencing nixpkgs.typstPackages.… directly, would yield less boilerplate and be easier to implement for you.
For refercence, the nixpkgs.typstPackages are populated in this file: https://github.com/NixOS/nixpkgs/blob/nixos-unstable/pkgs/by-name/ty/typst/typst-packages.nix#L39
Mostly, I'm just curious on the advantages of downloading the packages manually.
Nice catch, I would assume @loqusion was not aware that typst packages are now in nixpkgs, since typix's first release is from March 2024, and typstPackages in nixpkgs if from April this year.
It would make sens to refactor typix to use typstPackages from nixpkgs then, I guess
For what its worth, the packages seem a little out of date though. For example, here is the query for my package frame-it.
If you follow the links, you can see that I already released version 1.2.0 over a month ago but in nixpkgs, it registers version 1.1.2 as the most recent. :/
You can certainly send an update request, or even better: an update PR for it over on nixpkgs, I just checked the PR that introduces typstPackages, it includes an update script (and also discussion for potentially changing the update script, and executing it automatically regularly).
Thanks for the motivation :) I'm going to look into it when I find time, thanks for looking into it 😄
Indeed, I did not know of Nixpkgs' typstPackages. The PR for it was not merged until after the PR for Typix's unstable_typstPackages was merged.
As far as I can tell from reading Nix documentation, Nixpkgs does not archive any packages anywhere, it just describes how to build them with Nix expressions. So both Typix and Nixpkgs are downloading package tarballs manually from https://packages.typst.org. Incidentally, this can lead to the issue of outdated hashes if the tarball gets replaced upstream, which involves a lot less boilerplate in Typix (at the time of writing this).
What Nixpkgs does that ~~Nintendon't~~ Typix does not currently do is keep a list of all Typst packages from Typst Universe that can be updated with a script[^1]. This list includes useful information like hashes and dependencies, so that you can use Typst packages without manually specifying those things like you need to do in Typix. This is a clear quality of life improvement that should be supported by Typix.
[^1]: Working CI is pending, hence the Typst packages list is not currently up to date, though there is an open PR to update it manually.
My only hesitation with supporting Nixpkgs' typstPackages is that certain types of implentation changes to buildTypstPackage or to typstPackages would cause Typix to break — for instance, if outDir were to change then Typix's assumption about the location of the package files would be violated. Furthermore, if Typix adopted the policy of only supporting (say) the latest nixpkgs-unstable, then these breaking changes would introduce version incompatibilities between Typix and Nixpkgs, meaning that if the version you use for one of them falls within a specific range, you must use a version of another within a specific range. Not documenting these version incompatibilities places a burden on the user, whereas documenting them consistently adds a maintenance burden. Having to worry about breaking changes in Typst is enough of a burden as-is; I'd rather not pile on to that with another layer of complexity.
I'd be happy to support Nixpkgs' typstPackages at some point in the future, when its interface can be guaranteed to be stable. In the meantime, I think it is worthwhile to include the aforementioned quality of life improvements in Typix so that dependencies and hashes don't have to be manually specified.
In other words, it would turn this example:
{
outputs = { typix }: let
system = "x86_64-linux";
in {
packages.${system}.default = typix.lib.${system}.buildTypstProject {
unstable_typstPackages = [
{
name = "cetz";
version = "0.3.4";
hash = "sha256-5w3UYRUSdi4hCvAjrp9HslzrUw7BhgDdeCiDRHGvqd4=";
}
# Transitive dependencies must be manually specified
# `oxifmt` is required by `cetz`
{
name = "oxifmt";
version = "0.2.1";
hash = "sha256-8PNPa9TGFybMZ1uuJwb5ET0WGIInmIgg8h24BmdfxlU=";
}
];
};
};
}
Into this:
{
outputs = { typix }: let
system = "x86_64-linux";
in {
packages.${system}.default = typix.lib.${system}.buildTypstProject {
unstable_typstPackages = [
{
# No hash, and no dependencies!
name = "cetz";
version = "0.3.4";
}
];
};
};
}
In fact, we could even go so far as this:
{
outputs = { typix }: let
system = "x86_64-linux";
in {
packages.${system}.default = typix.lib.${system}.buildTypstProject {
unstable_typstPackages = [
{
# No hash, dependencies, or version!
name = "cetz";
}
];
};
};
}
In this latter case, the "latest" (according to Typix's Typst package list, updated regularly with CI) version would be used, foregoing the need for the user to manually check what the latest version of the package they want to use is.
(Of course, hashes, dependencies, and versions could always be manually specified — the point is that they should be optional.)
TL;DR: I probably won't support Nixpkgs' typstPackages at this time, but I can bring its quality of life improvements to Typix!
Ah didn't realize this is already an opened issue already. Regardless, an implemented support is on this PR https://github.com/loqusion/typix/pull/61. I would agree on that relying on the upstream nixpkgs would be troublesome sometimes as if the package is outdated (I have plan on integrating typst packages update script into nixpkgs's CI, but haven't done it yet). This is why I kept two package sources separate in my PR.
(correct me if i am wrong with that) wouldnt it be most convinient if you could just:
# rdrk where i need to define them yet lmao
packages = with pkgs.typstPackages [
# your plugins
touying
];
(please excuse the clueless looking example - i discovered this project 10 minutes ago and now want to use it)
(correct me if i am wrong with that) wouldnt it be most convinient if you could just:
# rdrk where i need to define them yet lmao packages = with pkgs.typstPackages [ # your plugins touying ];(please excuse the clueless looking example - i discovered this project 10 minutes ago and now want to use it)
It would just copy packages from Typst Universe to a nix path. You still need to tell Typst where to find these packages.
Heads-up, if anyone needs this functionality now, it's supported by Press
Typst packages are supported in Typix, though the base case is a bit cumbersome right now! I will merge support for Typst packages from nixpkgs some time in mid- to late-December, I'm just pretty busy at the moment.
No worries, I know how it is. Just wanted to help out others with similar issues. Spent some time trying to figure out what my options were. I initially tried out the PR's but wasn't succesful, and specifying the hashes as I would have to do in the main branch was a pain.