I have been wanting to have a personal blog for a while now. It has been quite difficult to keep up with my writing, both technical and personal, and a personal blog sounded like the ideal way to go about it. In particular considering the current state of the Internet.
In this page I wanted to leave some thoughts on how I setup my Quartz repository.
Nix flake
I have been infatuated with Nix for about half a year now. For those that might be unaware, Nix is a programming language and packaging tool that lets you setup reproducible and declarative environments. I don’t really have ways to use it in my day-to-day job, but for personal projects the first thing I am always doing is setting up a nix flake.
Since I am still a youngling with respect to Nix, I tend to look around for how people solved the problem first. To build Quartz and its development environment, I needed a flake that would give me a devshell with
- NodeJS and the quartz dependencies setup.
- A personalized neovim environment.
The flake I ended up writing is based on this blogpost. You can of course take a look at it in this blog’s repository, but for those curious
{
description = "Quartz personal flake";
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
flake-utils.url = "github:numtide/flake-utils";
nixvim_config.url = "github:AlejandroGomezFrieiro/nixvim_config";
gitignore = {
url = "github:hercules-ci/gitignore.nix";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs = {
self,
nixpkgs,
nixvim_config,
flake-utils,
gitignore, ... }:
flake-utils.lib.eachDefaultSystem (system:
let
pkgs = import nixpkgs { inherit system; };
nodejs = pkgs.nodejs_20;
node2nixOutput = import ./nix { inherit pkgs nodejs system; };
# NOTE: may want to try https://github.com/svanderburg/node2nix/issues/301 to limit rebuilds
nodeDeps = node2nixOutput.nodeDependencies;
app = pkgs.stdenv.mkDerivation {
name = "example-ts-node";
version = "0.1.0";
src = gitignore.lib.gitignoreSource ./.;
buildInputs = [ nodejs ];
buildPhase = ''
runHook preBuild
# symlink the generated node deps to the current directory for building
ln -sf ${nodeDeps}/lib/node_modules ./node_modules
export PATH="${nodeDeps}/bin:$PATH"
npm run build
runHook postBuild
'';
installPhase = ''
runHook preInstall
# Note: you need some sort of `mkdir` on $out for any of the following commands to work
mkdir -p $out/bin
# copy only whats needed for running the built app
cp package.json $out/package.json
cp -r dist $out/dist
ln -sf ${nodeDeps}/lib/node_modules $out/node_modules
# copy entry point, in this case our index.ts has the node shebang
# nix will patch the shebang to be the node version specified in buildInputs
# you could also copy in a script that is basically `npm run start`
cp dist/index.js $out/bin/example-ts-nix
chmod a+x $out/bin/example-ts-nix
runHook postInstall
'';
};
neovimModule = {
inherit pkgs;
module = {
imports = [
nixvim_config.outputs.nixosModules.${system}.nvim
];
plugins.lsp.servers.markdown_oxide.enable = true;
plugins.lsp.servers.tsserver.enable = true;
extraPlugins = with pkgs.vimPlugins; [
markdown-nvim
];
extraConfigLua = "require('markdown').setup()";
};
};
neovim = nixvim_config.inputs.nixvim.legacyPackages.${system}.makeNixvimWithModule neovimModule;
in with pkgs; {
defaultPackage = app;
devShell = mkShell { buildInputs = [ just neovim markdown-oxide nodejs node2nix ]; };
});
}
Neovim configuration
I have tested Neovim oxide in the past together with markdown.nvim and I find the markdown-first knowledge management to be quite efficient, so I decided to set them up together in this project. Markdown oxide gives me an Obsidian-like way to interconnect my notes through a Language Server Protocol (LSP), while markdown.nvim
just has nice functionality to work with markdown.
For example, to make the following word bold, all that is needed is to select it in visual mode and press gsb
. This can also be done in Normal mode to make this word italic with gswi
. Neovim is truly magic. There is also LSP-support for adding internal links through typing [[
, like it’s done here to link to the index.
Justfile
Just is an alternative to makefile with very simple syntax. I am still trying to figure out how the more complicated features and recipes work, but I can quickly serve this Quartz blog by running
just serve
Setting up direnv for easy reloading
It is a bit annoying to have to run nix develop
every time I want to enter the environment. direnv allows one to setup the devshell whenever one enters the environment. On top of it, we can set nix-direnv for the nix-part of the setup to work a lot better, and spend a lot less time setting up environments.
Once direnv
is setup, one just needs to make a .envrc
file in the same folder as the project.
if ! has nix_direnv_version || ! nix_direnv_version 3.0.6; then
source_url "https://raw.githubusercontent.com/nix-community/nix-direnv/3.0.6/direnvrc" "sha256-RYcUJaRMf8oF5LznDrlCXbkOQrywm0HDv1VjYGaJGdM="
fi
use flake
Now, after we run direnv allow
, it will setup everything! Now whenever you enter the folder, if the flake.nix
file has not changed, you will have your development environment ready.
Public comments
As a way to increase interactiviy on the site, I am attempting to setup comments using Giscus. I followed the instructions in the quartz documentation and they show locally, so I hope they will also show up in the online version.
Conclusion
Overall I am quite happy with the setup. I just need to clone the repo and run nix develop
to start writing anywhere (I hope! Fingers crossed!).