Gram
Gram is a hard fork of Zed removing AI integration and telemetry as well as no user agreement or subscription, among other features. For more on the reasoning for and purpose of the fork see the mission statement. For general Gram information see the docs.
Installation
Gram is available in nixpkgs as gram. You can add it to system packages with
environment.systemPackages = with pkgs; [
gram
];
Installing Extensions
Gram, unlike Zed, builds extensions locally. This makes getting extensions working on NixOS require some configuration. There are multiple ways to handle extensions, in no particular order:
- System Method: if you don't mind modifying your system configuration, requires Nix-ld.
- Nix-Gram-Extensions: if you want to manage extensions with home manager or hjem
- Temp FHS Environment: if you don't want to modify your system. Includes full copy-pastable example.
System Method
This allows you to use Gram as you'd expect on other distros, able to click Install From URL or Install Local and have Gram compile the extension. This method is a bit hacky, and requires some setup.
There are a number of known things needed for Gram to successfully compile extensions itself. Aside from #Nix-ld, which needs to be enabled in your system configuration, everything else can be installed either to system packages, in a devShell, user packages, home manager packages, etc. All examples are primarily for reference, and will only demonstrate installation to system packages. If you want to install using any of the previously listed methods, it should hopefully be fairly simple to translate to your method of choosing.
The known requirements are the following:
Nix-ld
Nix-ld must be enabled on the system. This is because Gram pulls in the wasi-sdk for portions of the compilation, and the binaries it pulls are made for normal Linux distributions, meaning the linker path they look for doesn't exist without Nix-ld. Enabling it is as simple as adding the following to your configuration.
{
programs.nix-ld.enable = true;
}
Clang
Clang must be installed and available under the cc alias, which is true as long as the wrapped clang (the ones referred to as clang-wrapper) is the one installed and it is not being overwritten by gcc.
You can verify if clang is configured correctly in your environment by opening Gram's terminal (ctrl+` or ctrl+shift+p > terminal panel: toggle) and running the following
clang --version
cc --version
Both should return with a version of clang.
Rust Wasm32-Wasip2
A valid wasm32-wasip2 rust toolchain needs to be installed into your environment.
This can be done declaratively with either #Fenix or #Rust-Overlay. Or you can have Gram install the toolchain itself by installing #Rustup to your environment.
The #Rustup option is less declarative, but much simpler if that doesn't bother you.
If you've installed with fenix or rust-overlay, you can confirm that it's installed correctly by entering Gram's terminal and running
ls $(rustc --print sysroot)/lib/rustlib
If in the command's output is a directory named wasm32-wasip2, it should be installed correctly and Gram will be able to detect it. If it's listed as wasm32-unknown-unknown, see Wasm32 Wrong Target.
Rustup
To configure rustup, just run
rustup default stable
As whatever user is using Gram to add the stable toolchain as your default to ~/.rustup.
Fenix
This example uses the latest branch, but other options are available, just make sure the versions all match across toolchain and targets or rustc, cargo and targets.
Add fenix to your flake
{
inputs = {
fenix = {
url = "github:nix-community/fenix";
inputs.nixpkgs.follows = "nixpkgs";
};
nixpkgs.url = "nixpkgs/nixos-unstable"; # or any other branch
};
}
{inputs, pkgs, system, ... }:
let
extension-toolchain = with inputs.fenix.packages.${system}; combine [
# full toolchain (not required):
# latest.toolchain
# minimum required to build:
latest.rustc
latest.cargo
# wasm32-wasip2 target (required):
targets.wasm32-wasip2.latest.rust-std
];
in
{
environment.systemPackages = with pkgs; [
clang
extension-toolchain
];
}
Rust-Overlay
Like the fenix example, this assumes the latest branch, though rust-overlay provides others.
Add rust-overlay to your flake
{
inputs = {
fenix = {
url = "github:nix-community/fenix";
inputs.nixpkgs.follows = "nixpkgs";
};
nixpkgs.url = "nixpkgs/nixos-unstable"; # or any other branch
};
}
{ inputs, pkgs, ... }:
{
nixpkgs.overlays = [ inputs.rust-overlay.overlays.default ];
environment.systemPackages = with pkgs; [
# full toolchain (not required):
# (rust-bin.stable.latest.default.override { targets = [ "wasm32-wasip2" ]; })
# minimum required to build:
(rust-bin.stable.latest.minimal.override { targets = [ "wasm32-wasip2" ]; })
];
}
Other Needed Packages
Nix-Gram-Extensions
Nix-Gram-Extensions is a project to bring declarative management of Gram extensions to Nix using custom builders and integration with home manager and hjem. It is hosted on codeberg and tangled. If you want to install it to your system, it has a detailed section on installation in its README. More information can be found at its discourse announcement.
Temp FHS Environment
If you do not want to or cannot enable Nix-ld, you can make a temporary FHS Environment and run Gram in there to build extensions. Provided below are an example flake.nix and shell.nix. Just add these files to a directory, enter it and run nix develop. Then, once you're dropped into the environment's shell, run gram and install your extensions as you would on any other distro. Once they're built, you can run Gram outside of that environment too and they should just work.
And of course, if you prefer #Fenix or #Rustup, you can modify this example to use them instead of #Rust-Overlay.
{
description = "Gram extensions flake";
inputs = {
nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable";
rust-overlay.url = "github:oxalica/rust-overlay";
};
outputs = {self, nixpkgs, rust-overlay}:
let
systems = nixpkgs.lib.platforms.linux ++ nixpkgs.lib.platforms.darwin;
forAllSystems = nixpkgs.lib.genAttrs systems;
in
{
devShells = forAllSystems (system:
let
overlays = [ (import rust-overlay) ];
pkgs = import nixpkgs {
inherit system overlays;
};
in
{
default = pkgs.callPackage ./shell.nix { };
});
};
}
{ pkgs }:
(pkgs.buildFHSEnv {
name = "gram";
targetPkgs = pkgs: (with pkgs; [
gram # (not needed if already installed to environment)
clang
(rust-bin.stable.latest.minimal.override { targets = [ "wasm32-wasip2" ]; })
git
]);
}).env
More About Extensions
Troubleshooting
Extensions
Wasm32 Wrong Target
If the wasm32 target is listed as wasm32-unknown-unknown, Gram will be unable to detect it and if rustup isn't installed it will error with failed to run `rustup target add`: no such file or directory, because when it doesn't detect an installed valid toolchain, it tries to install one with rustup. This has happened on fenix's stable branch and was fixed by changing to the latest branch.