NEWC++ for beginners — without CMake pain

The friendlyC++ bootstrapper
you’ve been waiting for.

Rivets handles the first 30 minutes of setting up a C++ project so you can focus on writing code, not fighting CMakeLists.txt. Wraps CMake + Clang/GCC in a modern, forgiving CLI.

riv init in 30s View sourceMIT • Go 1.23+ • Linux
No build scripts in packages Standard CMake eject Zero config
< 1 min
Time to hello
4
Commands
0
Lock-in
zsh — riv
$riv doctor
clang++ 17.0.6 /usr/bin/clang++
cmake 3.28.1 /usr/bin/cmake
ninja 1.11.1
✔ All good — you can build.
$riv init hello-world
created hello-world/riv.toml
created hello-world/src/main.cpp
created hello-world/lib/.keep + include/.keep
$riv run
$ cmake -S .riv -B .riv/build — generated
$ cmake --build .riv/build — built 0.9s
Hello from riv!
2 + 3 = 5
Copy & try it
Trusted workflow Clang / GCC auto-detected CMake • Ninja compile_commands.json for IDEDocs on GitHub
Why Rivets

Focus on C++. Not on build scripts.

Four commands handle the whole lifecycle — from doctor to run — with a layout that scales from hello-world to small game engines.

riv doctor

Detects clang++/g++, cmake, ninja. Tells you exactly what to install — no guessing.

riv init

Scaffolds riv.toml, src/main.cpp, lib/ and include/ with .keep files. Clean, scalable.

riv build

Scans src/lib/include, validates, generates .riv/CMakeLists.txt and invokes CMake.

riv run

Incremental build + run + arg forwarding: riv run -- --flag. It just works.

No lock-in

Generated CMake is standard and readable. Keep it and walk away whenever you want.

Secure by default

No build scripts in packages. Dependencies are data, not arbitrary code execution.

How it works

Four steps. Transparent every time.

No hidden state. Everything lands in .riv/ so your root stays clean.

Your IDE gets compile_commands.json for full IntelliSense in VS Code / CLion — no extra config.
01
Scan

Find .cpp/.h in src/, lib/*, include/

02
Validate

Reject bad layouts with friendly fix hints

03
Generate

Render CMakeLists.txt.tmpl into .riv/

04
Execute

cmake -S .riv -B .riv/build → build

riv.toml — tiny manifest

name = "hello-world"
version = "0.1.0"
standard = "17"

Allowed auto-link

Any folder in lib/ with src/ + include/<name> becomes a static lib and is linked automatically.

Binary output

Your executable is at .riv/build/<name>. Root stays clean; build artifacts are gitignored.
Convention over configuration

A layout that scales with you.

Opinionated, minimal, and familiar to any C++ dev. Start small — grow without restructuring.

# after riv init myapp
myapp/
├── riv.toml # name, version, standard
├── src/
└── main.cpp # entry point
├── lib/ # local libs — auto linked
└── graphics/
├── include/graphics/
└── src/
├── include/ # header-only
└── utils/
└── .riv/ # generated, gitignored
src/
app logic
lib/
modules
riv.toml
manifest

src/main.cpp

#include <iostream>

int add(int a, int b) { return a + b; }

int main() {
  std::cout << "Hello from riv!\n";
  std::cout << "2 + 3 = " << add(2, 3) << "\n";
  return 0;
}

Daily flow

$ riv build -j 4
— generates .riv/CMakeLists.txt and compiles
$ riv run -- --verbose
— forwards args to your binary
Supports compile_commands.json for VS Code & CLion IntelliSense out of the box.

Commands reference

Four commands. No flags to memorize.

Command
What it does
Example
riv doctor
Validates toolchain (clang++/g++, cmake, ninja)
riv doctor
riv init <name>
Creates project scaffold
riv init game_engine
riv build
Generates CMake & compiles
riv build -j 4
riv run
Builds if needed & runs executable
riv run -- --flag
Quick start

Up and running in 30 seconds.

Go 1.23+ required. For everyone else, binaries are on the way.

go install github.com/Akash97p/rivets/cmd/riv@latest

Ensure $(go env GOPATH)/bin is in your PATH.

1riv doctor — verify clang/cmake
2riv init hello-world && cd hello-world
3riv run — hello from riv!

What you get

Beginner-friendly defaults, pro-ready output.

Secure — no build scripts in packages, ever.
Portable — readable CMake you can eject with.
Fast feedback — incremental builds in .riv/build.
# riv.toml
name = "hello-world"
version = "0.1.0"
standard = "17"

Security first

Downloading a library never runs arbitrary code. Dependencies are declared data.

No lock-in

Generated CMake is yours. Outgrow Rivets? Take it with you, no migration.

Fail loudly

Invalid layout → precise error + fix hint. No silent breakage.

Roadmap

What’s done and what’s intentionally deferred.

Project scaffolding
CMake generator
Build & Run + doctor
Native Windows support
Native macOS support
Test runner integration
Dependency management — deferred by designintentionally not now

Open source • MIT

Built for learners, by learners. Contributions welcome — especially from beginners.

Fork → branch → go test ./...go fmt → PR.

Acknowledgments

Go team for the stdlib. CMake, Clang & GCC for powering C++. And you — for giving Rivets a try.
Rivets logoThe rivet-shaped R is Rivets’ mark — see assets/branding.

Ready to rivet your first project?

One command to scaffold, one to run. The rest is just C++.

Star on GitHub
$ riv init myapp && riv run