Installation
This guide shows how to add Hindsight to your Haskell project.
Two Ways to Add Hindsight
You can add Hindsight to your project either way:
With Nix Flakes - Reproducible builds with binary cache support
Without Nix - Plain
cabal(fetches dependencies from GitHub)
Choose whichever fits your workflow.
Option A: With Nix Flakes
Prerequisites:
Nix with flakes enabled:
echo "experimental-features = nix-command flakes" >> ~/.config/nix/nix.conf
Setup:
Add to your flake.nix:
{
description = "My Hindsight project";
nixConfig = {
extra-substituters = [ "https://hindsight-es.cachix.org" ];
extra-trusted-public-keys = [
"hindsight-es.cachix.org-1:2UQwF1OeL+6JQqIEhPXRivkNIRuO5dNcBrWYZ3vbpWk="
];
};
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
hindsight.url = "github:hindsight-es/hindsight/main";
hindsight.inputs.nixpkgs.follows = "nixpkgs"; # Maximize cache hits
};
outputs = { self, nixpkgs, hindsight }:
let
system = "x86_64-linux"; # or aarch64-darwin, etc.
pkgs = nixpkgs.legacyPackages.${system};
haskellPackages = pkgs.haskell.packages.ghc910.extend (self: super: {
my-project = self.callCabal2nix "my-project" ./. {};
# Import Hindsight packages from flake input
hindsight-core = hindsight.packages.${system}.hindsight-core;
hindsight-memory-store = hindsight.packages.${system}.hindsight-memory-store;
hindsight-postgresql-store = hindsight.packages.${system}.hindsight-postgresql-store;
hindsight-postgresql-projections = hindsight.packages.${system}.hindsight-postgresql-projections;
});
in {
packages.${system}.default = haskellPackages.my-project;
devShells.${system}.default = haskellPackages.shellFor {
packages = p: [ p.my-project ];
buildInputs = [ pkgs.haskellPackages.cabal-install ];
};
};
}
Binary Cache:
The nixConfig section automatically configures the Hindsight cachix cache for pre-built binaries.
Trusted users (in
/etc/nix/nix.conf): Works automaticallyOther users: You’ll see a warning about “ignoring untrusted flake configuration”
The cache won’t work unless your system administrator either:
Adds you to
trusted-usersin/etc/nix/nix.conf, ORAdds
https://hindsight-es.cachix.orgtotrusted-substituters
If the cache isn’t available, the first build will compile from source (a few minutes).
Option B: Without Nix
Prerequisites:
GHC 9.10+
Cabal 3.8 or later
Git (for fetching dependencies)
Setup:
Add to your cabal.project:
packages:
./your-package.cabal
source-repository-package
type: git
location: https://github.com/hindsight-es/hindsight.git
tag: main
subdir: hindsight-core
source-repository-package
type: git
location: https://github.com/hindsight-es/hindsight.git
tag: main
subdir: hindsight-memory-store
-- Optional: Add other backends as needed
-- hindsight-filesystem-store
-- hindsight-postgresql-store
-- hindsight-postgresql-projections
Add to your .cabal file:
build-depends:
base >= 4.18 && < 5,
hindsight-core,
hindsight-memory-store,
-- Optional: add other backends
-- hindsight-postgresql-store,
-- hindsight-postgresql-projections,
aeson,
text,
uuid
default-extensions:
DataKinds
DeriveAnyClass
DeriveGeneric
DuplicateRecordFields
OverloadedRecordDot
OverloadedStrings
RequiredTypeArguments
TypeApplications
TypeFamilies
On first build, Cabal will fetch Hindsight packages from GitHub.
Available Packages
Core Library:
hindsight-core- Type-safe event system with versioning (required)
Storage Backends:
hindsight-memory-store- In-memory event store (testing/development)hindsight-filesystem-store- File-based event persistencehindsight-postgresql-store- PostgreSQL event store with ACID guarantees
Projection System:
hindsight-postgresql-projections- Backend-agnostic projection system (always uses PostgreSQL for execution)
Basic Usage
Import Hindsight modules:
import Hindsight
import Hindsight.Store.Memory (newMemoryStore)
-- For PostgreSQL:
-- import Hindsight.Store.PostgreSQL (newSQLStore, createSQLSchema)
-- import Hindsight.Projection (runProjection)
PostgreSQL Setup
For PostgreSQL backend and projections, you need a running PostgreSQL instance.
The schema is automatically created when you initialize the store:
import Hindsight.Store.PostgreSQL (createSQLSchema, newSQLStore)
import qualified Hasql.Pool as Pool
main = do
pool <- createPool postgresSettings
-- Create schema (idempotent - safe to run multiple times)
_ <- Pool.use pool createSQLSchema
store <- newSQLStore connStr
Example Project
See the Hindsight example repository for a complete, runnable example demonstrating:
Event definitions
Event storage
Event subscriptions
Both Nix and non-Nix builds
Next Steps
Continue to Getting Started with Hindsight to learn how to define events and build event-sourced applications with Hindsight.