Rivets Docs
The friendly C++ bootstrapper. This wiki covers installs, commands, project layout and pro tips — written so even if today is your Day 1 in C++, you’ll feel at home.
Introduction
Rivets (riv) removes the first 30 minutes of C++ pain: CMake boilerplate, folder linking, and “where do I put my files?”. You write src/main.cpp, Rivets generates a clean, standard CMake project in .riv/ and builds it. It’s not a package manager (yet), it’s training wheels — you learn CMake by reading what we generate.
For beginners
riv init → riv run and you’re coding.No lock-in
Fast
.riv/build stays out of your way.Installation
Requires Go 1.25+ to install from source, plus a C++ compiler and CMake on your machine.
Option A — Go install (recommended)
Works on Linux, macOS (WSL on Windows)
go install github.com/Akash97p/rivets/cmd/riv@latest
riv --version
riv doctorMake sure $(go env GOPATH)/bin is in your PATH.
Option B — From source
Clone and build locally
git clone https://github.com/Akash97p/rivets.git
cd rivets
go build -o riv ./cmd/riv
./riv --helpclang++ ≥10 or g++ ≥9 and cmake ≥3.16 (3.22+ recommended). Run riv doctor to verify. Install hints: sudo apt install build-essential cmake clang-format clang-tidy or brew install llvm cmake.Quick Start — 60 seconds
# 1) Check your toolchain
riv doctor
# 2) Create a project (full = with sample lib + header)
riv init hello --std c++20
cd hello
# 3) Build & run
riv build
riv run
# Hello from riv!
# 2 + 3 = 5src/main.cpp and hit riv run again — incremental build, no CMake touching. Try riv run --watch for auto-rebuild.Your First Project — Step by Step
1. Make the project
riv init mygame --template fullCreates riv.toml, src/main.cpp, sample lib and a .gitignore already ignoring .riv/.
2. Add your code
// src/main.cpp
#include <iostream>
int main(){
std::cout << "My game starts\n";
}3. Create a library (optional but encouraged)
Each folder in lib/ becomes a static library automatically.
mkdir -p lib/physics/include/physics lib/physics/src
# lib/physics/include/physics/physics.h -> int update();
# lib/physics/src/physics.cpp -> implementation
riv build # links automatically
Why Rivets?
| Problem | Without Rivets 😵 | With Rivets ✅ |
|---|---|---|
| Start a project | Write 40-line CMakeLists by hand | riv init → ready |
| Add a library | Edit CMake, add_subdirectory, target_link… | Create lib/mylib/ → auto linked |
| IDE support | Configure compile_commands manually | We symlink it to root — clangd just works |
| Errors | Cryptic CMake dump | Friendly Hints: “move .cpp out of include/” |
Project Structure
mygame/
├── riv.toml # your manifest
├── src/main.cpp # entry point (must exist)
├── lib/ # compiled libs → auto static libs
│ └── physics/
│ ├── include/physics/
│ │ └── physics.h
│ └── src/
│ └── physics.cpp
├── include/ # header-only libs
│ └── utils/utils.h
├── external/ # riv add deps live here
└── .riv/ # generated CMake + build (gitignored)
├── CMakeLists.txt
└── build/myapp
Folder rules (enforced)
include/ and src/. All .cpp under src/ (recursive) are compiled..cpp allowed (we error with a Hint).include/, heavy modules in lib/.riv.toml Explained
Tiny, human manifest — alternative to CMake boilerplate.
name = "mygame"
version = "0.1.0"
standard = "c++20"
[build]
warnings = "all"
[dependencies]
stb_image = "2.28"
Fields
name — binary name + project folder.standard — c++17 | c++20 | c++23 (validated).[build] — for future flags (warnings, sanitize).[dependencies] — added by riv add; lock details live in riv.lock.standard to c++23 and rebuild — we generate CMAKE_CXX_STANDARD 23 for you.How It Works
src/, lib/*/src (recursive), include/, external/..cpp in include/, spaces/symlinks, missing src/main.cpp with friendly Hints.internal/generator/templates/CMakeLists.txt.tmpl with file lists.cmake -S .riv -B .riv/build -DCMAKE_BUILD_TYPE=Release|Debug → cmake --build. Binary lands at .riv/build/<name>. We also symlink compile_commands.json to root for clangd.riv doctor first run --json
Diagnose your C++ toolchain and get OS-specific install hints.
riv doctor
riv doctor --json | jq- OS: Linux native / macOS experimental / Windows WSL hint
- Compiler: clang++ → g++ → cl, version ≥ clang 10 / gcc 9
- CMake: ≥3.16 (warn if <3.22)
- Build test: compiles a hello.cpp
- Run this first on a new laptop.
--jsonis great for CI: fails the job if Ready=false.- If it says “Not found”, copy the Hint line.
riv init / riv new scaffold
Create a new project. new is an alias.
riv init myapp --std c++20
riv init myapp --template minimal # no sample lib
riv init myapp --minimal --no-git
riv new myapp --std c++23 # same as init| Flag | Default | Notes |
|---|---|---|
| --std | c++20 | c++17/20/23 validated, normalized to “20” for CMake |
| --template | full | full (with lib/sample + utils) / minimal / lib |
| --minimal | false | Shorthand for --template minimal — tiny hello-world |
| --no-git | false | Skip git init |
^[a-zA-Z0-9_-]+$ — no spaces/slashes. Directory must not already exist.riv build --release / --clean / -j / -v
Generate CMake and compile. Smart about caching.
riv build
riv build --release -j 8
riv build --clean --verbose
riv build --debug --clean| Flag | What |
|---|---|
| -j, --jobs | Parallel jobs (default: CPU cores) |
| --release | CMAKE_BUILD_TYPE=Release (optimized) |
| --debug | Debug (default) |
| --clean | Remove .riv before build |
| -v, --verbose | Show cmake / build logs |
.riv/CMakeLists.txt — edit your .cpp files and rebuild. Binary goes to .riv/build/<name>. We also symlink compile_commands.json to the root so VS Code / CLion IntelliSense just works.riv run build+run --watch
Builds if needed, then runs your binary and forwards args.
riv run
riv run -- --my-flag hello # args after -- go to your program
riv run --no-build # skip build, just run
riv run --release # build Release then run
riv run --watch # auto-rebuild on savesrc/, lib/, include/ for .cpp/.h/.hpp changes and re-runs. Great for live tweaking. Ctrl+C to stop.riv clean
Wipe build artifacts, keep your source.
riv clean
riv build --clean # clean + build in one goDeletes .riv/ and the compile_commands.json symlink. Use when CMake cache feels stale.
riv fmt --check
Format all C++ files with clang-format.
riv fmt # format in place
riv fmt --check # CI mode: fail if not formattedWalks src/, lib/, include/. We ship a default .clang-format (Google, 4 spaces, 100 cols) at riv init. Customize it — we respect yours.
clang-format in PATH. Hint: sudo apt install clang-format.riv check
Lint without building — validates layout + runs clang-tidy if available.
riv checkAlways validates src/main.cpp, lib layout, no .cpp in include/, no symlinks, riv.toml fields. If .riv/build/compile_commands.json exists and clang-tidy is installed, it also lints — otherwise it tells you to run riv build first. Perfect pre-commit.
riv info --json
Debug helper — see what Rivets discovered.
riv info
riv info --json | jqPrints project name / version / standard, main entry, every lib with its source count, include dirs and external deps. Use when “it builds on my machine” and you want to see what scan found vs what you expected.
Dependencies — add / remove / list / search
Curated, offline-friendlyRegistry. Dependencies are vendored into external/ and locked in riv.lock with SHA256.
riv search # list all packages
riv search stb # filter
riv add stb_image # -> external/stb_image/ + riv.toml + riv.lock
riv list # show what's installed
riv remove stb_image- Finds
registry.toml(repo or project root). - Clones to
~/.cache/riv/repos/<pkg>, checks out commit. - Copies listed
includefiles toexternal/<pkg>. - Writes
riv.lockwith SHA256 checksums.
- We auto-add
../externalto your CMake includes — just#include "stb_image.h". riv searchwithout a query lists everything — great to browse.- Deps are data, not code execution — no build-script surprises (philosophy).
stb_image 2.28 (header-only) from nothings/stb. We keep it tiny on purpose; expansion is roadmapped but deferred while core stabilizes.riv test
Runs CTest if your build registered tests.
riv test
riv test --verbose
ctest --test-dir .riv/build --output-on-failure # same thing manuallyNeeds a build that calls enable_testing() / add_test(). If no tests are registered, we print a helpful hint instead of failing. Perfect for the upcoming “Test runner integration” milestone.
Shell Completion
Autocomplete for bash / zsh / fish / PowerShell — powered by Cobra.
# Bash (add to ~/.bashrc)
source <(riv completion bash)
# Zsh
riv completion zsh > "${fpath[1]}/_riv"
# Fish
riv completion fish | source
# PowerShell
riv completion powershell | Out-String | Invoke-ExpressionGuides
Adding a Local Library (the Rivets way)
# 1. Create the folders
mkdir -p lib/net/include/net lib/net/src
# 2. Add header + source
# lib/net/include/net/net.h
# lib/net/src/net.cpp
# 3. Just build — it auto-links
riv build
# CMake got: add_library(net ../lib/net/src/net.cpp)
# target_include_directories(net PUBLIC ../lib/net/include)
# target_link_libraries(myapp PRIVATE net)No riv.toml edits needed. Delete the folder to remove it.
Header-only vs Compiled — which folder?
Header-only → include/
.h/.hpp files, no .cpp. Example: include/utils/utils.h with inline funcs. Auto on include path.Compiled → lib/<name>
include/<name>/ headers + src/ sources → builds a static lib and links to your exe.Formatting & Linting
riv fmt uses your .clang-format if present, else our default (Google, 100 cols). Add riv fmt --check to CI.riv check validates layout always; with compile_commands.json + clang-tidy it lints deeply.Watch Mode
Want instant feedback while tweaking?
riv run --watch
# edit src/main.cpp → save → auto rebuild + rerun
# Ctrl+C to exitIDE Setup — VS Code & CLion
VS Code
.riv/build/compile_commands.json → ./compile_commands.json — IntelliSense just works after riv build.CLion
.riv/CMakeLists.txt automatically..riv/ as excluded if you like.