smolgit is a minimalist Git server written in Go with a React/TS frontend. It exposes a REST API over HTTP and an SSH interface.
cmd/– main entry point.pkg/– core libraries: ssh, git, config, model, route, etc.frontend/– React/TS UI, built intodist/and embedded viago:embed.test/– Bats integration tests.Makefile– build & tooling targets..github/workflows/– CI.
| Target | Description | Command |
|---|---|---|
build |
Compile Go binary into bin/smolgit |
make build |
build-frontend |
Build React assets into dist/ |
make build-frontend |
build-docker |
Build Docker image | make build-docker |
run |
Run compiled binary locally | make run |
run-docker |
Run smolgit in a container | make run-docker |
config |
Generate default config to stdout | make config |
config-docker |
Generate config for Docker | make config-docker |
clean |
Remove build artifacts | make clean |
lint |
Run golangci-lint on Go code | make lint |
test |
Run Go unit tests | make test |
integration-test |
Run Bats integration tests | make integration-test |
help |
Show available make targets | make help |
# Build image
make build-docker
# Generate config
make config-docker
# Run
docker run -it -p 3080:3080 -p 3081:3081 -v $(pwd)/:/etc/smolgit smolgitConfiguration is supplied as YAML. The default location is ./config.yaml or $HOME/.config/smolgit/config.yaml. It can be generated with:
./bin/smolgit config > config.yamlA minimal example:
log:
# Color log output
color: true
# Log as json
json: false
# Log level (INFO, DEBUG, TRACE, WARN)
level: DEBUG
server:
jwt_key: "super-salt"
auth_disabled: false
# Disable web server
disabled: false
# Web server address
addr: ":3080"
# Navbar brand string
brand: "smolgit"
ssh:
# SSH server address
addr: ":3081"
git:
# Folder to save git repositories
path: ./tmp
# Base for clone string formating
# (e.g. ssh://git@my-git-server.lan/myuser/project.git)
base: "git@my-git-server.lan"
users:
- name: "bob"
password: "$2y$05$US7wXbew8P9d2h8qL3aC6OMhVcwO.1W6U.hVFBGNj9o9YQO.cSqd2" # htpasswd -nbB admin MySecret123
role: "admin"
keys:
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQ... developer@mail.comserver.jwt_keyis mandatory – without it the server will refuse to start.git.pathcan point to a localgitbinary; if omitted the binary defaults to/usr/local/bin/git.git.userscontrols SSH access; each user has a list of public keys and a role string.
The UI is built with Vite + React + TypeScript. Development can be run in isolation:
cd frontend
pnpm install
pnpm dev # hot‑reload server at http://localhost:5173Production build (used by the binary) is performed by make build-frontend. The resulting dist/ folder is embedded into the Go binary via go:embed.
Linting the frontend code uses ESLint:
cd frontend
pnpm run lintmake testmake integration-testThe Bats tests start a temporary smolgit instance, exercise the CLI, and verify HTTP responses.
GitHub Actions runs:
make buildmake lintmake configmake integration-test
See .github/workflows/test.yml for details.
| Area | Convention |
|---|---|
| Go packages | lowercase, no underscores |
| Go identifiers | camelCase for variables, PascalCase for exported types |
| Go structs | Tags use koanf style |
| Frontend | PascalCase components, camelCase props |
| Paths | Use relative paths in imports (e.g. smolgit/pkg/git) |
- Config path – if you run
make runthe binary looks for./config.yamlor$HOME/.config/smolgit/config.yaml. If you use Docker, mount the config into/etc/smolgit. - JWT key – the server refuses to start without
server.jwt_key. Generate a random string or useopenssl rand -base64 32. - Git base –
git.baseshould match the SSH prefix used by clients, e.g.git@my-git-server.lan. Otherwisegit clonewill fail. - Frontend build – the binary embeds the built assets. Do not copy the
distfolder manually; always runmake build-frontendafter changes.
Follow the existing style. Run:
make lint
make testbefore pushing. Use the PR title format [smolgit] <Title>.
Follow Conventional Commits:
feat: A new featurefix: A bug fixdocs: Documentation only changesrefactor: A code change that neither fixes a bug nor adds a featuretest: Adding missing testscoauth: Co-authored changes (e.g., "Co-authored-by: Qwen3 ")- Example:
fix(core): format New function to pass gofumpt (coauth: Qwen3)
# Show Go build info
go list -m -u all
# View lint output
make lint
# View test coverage
go test -cover ./...
# Run frontend dev server
cd frontend && pnpm dev