Tinker π οΈ
A project-aware CLI for database, API, and gRPC interaction β inspired by Laravel Tinker, built for Go (and any language).
Tinker composes best-in-class open source tools (usql, httpie/curlie, grpcurl/evans) into a unified interface. It reads your project's tinker.toml and .env to automatically configure connections, so you can jump straight into working with your project.
Why Tinker?
If you've used Laravel Tinker, you know the workflow: open a shell, query the database, call an API endpoint, test a service β all within your project context. Go doesn't have an equivalent because it's compiled, not interpreted.
Tinker takes a different approach. Instead of trying to be a REPL for Go code, it:
- Reads your project's existing config (
.env, tinker.toml) β no wrapper abstractions
- Composes proven OSS tools β
usql for DB, httpie for HTTP, evans/grpcurl for gRPC
- Defines a simple contract β any project that implements
tinker.toml gets the full experience
- Works with any language β not just Go! Any project with a
.env and tinker.toml works
Quick Start
Install
One-line install (recommended) β installs binary + configures PATH:
curl -fsSL https://raw.githubusercontent.com/mvaliolahi/tinker/main/install.sh | bash
Or manually with Go:
go install github.com/mvaliolahi/tinker/cmd/tinker@latest
# Then add to PATH (if not already):
export PATH="$(go env GOPATH)/bin:$PATH"
Initialize
cd your-project
tinker init
Tinker will scan your project for:
.env files with DATABASE_URL, API_BASE_URL, GRPC_ADDR, etc.
- OpenAPI/Swagger spec files
.proto directories
- SQLite database files
And generate a tinker.toml:
# tinker.toml
[database]
source = "env:DATABASE_URL"
type = "postgres"
[api]
base_url = "env:API_BASE_URL"
spec = "openapi.yaml"
auth = "env:API_TOKEN"
auth_type = "bearer"
[grpc]
addr = "env:GRPC_ADDR"
proto_dir = "./proto"
reflection = true
Use
# Open interactive database session (usql)
tinker db
# Quick database queries
tinker db tables
tinker db describe users
tinker db count users
tinker db find users 1
tinker db exec "SELECT * FROM users LIMIT 5"
# Call API endpoints
tinker api GET /users
tinker api POST /users '{"name": "Ali"}'
tinker api PUT /users/1 '{"name": "Updated"}'
tinker api DELETE /users/1
# gRPC interactions
tinker grpc # Interactive REPL (evans)
tinker grpc list # List services
tinker grpc describe UserService
tinker grpc call UserService/GetUser '{"id": 1}'
# Run one-off Go code in project context
tinker run 'fmt.Println("Hello from tinker!")'
The Contract
The tinker.toml file is Tinker's contract with your project. It's declarative, minimal, and language-agnostic.
Full Spec
[database]
# How to get the connection string:
# "env:VAR_NAME" β read from environment variable (supports .env)
# "postgres://user:pass@host:5432/db" β direct DSN
source = "env:DATABASE_URL"
# Database type: postgres, mysql, sqlite3, sqlserver, mongodb
type = "postgres"
# Override the driver name (optional)
driver = ""
[api]
# Base URL for API calls
base_url = "env:API_BASE_URL"
# Path to OpenAPI/Swagger spec (optional β enables autocomplete)
spec = "openapi.yaml"
# Auth token source
auth = "env:API_TOKEN"
# Auth type: bearer, basic, api_key, or raw
auth_type = "bearer"
# Additional default headers
[api.headers]
X-Custom-Header = "value"
[grpc]
# gRPC server address
addr = "env:GRPC_ADDR"
# Directory containing .proto files
proto_dir = "./proto"
# Enable gRPC server reflection
reflection = true
# Custom project commands
[commands]
migrate = "go run ./cmd/migrate"
seed = "go run ./cmd/seed"
test = "go test ./..."
Environment Variable Resolution
Any value starting with env: is resolved from the environment. Tinker automatically loads .env files, so this works:
# .env
DATABASE_URL=postgres://user:pass@localhost:5432/mydb
API_BASE_URL=http://localhost:8080
API_TOKEN=secret-token
# tinker.toml
[database]
source = "env:DATABASE_URL"
type = "postgres"
[api]
base_url = "env:API_BASE_URL"
auth = "env:API_TOKEN"
auth_type = "bearer"
Prerequisites
Tinker orchestrates existing tools. Install the ones you need:
| Tool |
Purpose |
Install |
| usql |
Database REPL |
go install github.com/xo/usql@latest |
| httpie |
HTTP client |
pip install httpie or brew install httpie |
| curlie |
HTTP client (alt) |
go install github.com/rs/curlie@latest |
| evans |
gRPC REPL |
go install github.com/ktr0731/evans@latest |
| grpcurl |
gRPC client |
go install github.com/fullstorydev/grpcurl/cmd/grpcurl@latest |
You don't need all of them β only install the tools for the features you use.
Architecture
βββββββββββββββββββββββββββββββββββββββββββ
β tinker CLI (Go) β
ββββββββββββββββ¬ββββββββββββ¬βββββββββββββββ€
β DB Module β API Moduleβ gRPC Module β
β (usql) β (httpie) β (evans/ β
β β /curlie) β grpcurl) β
ββββββββββββββββ΄ββββββββββββ΄βββββββββββββββ€
β Config Layer β
β (tinker.toml + .env resolver) β
βββββββββββββββββββββββββββββββββββββββββββ€
β Auto-Detection Engine β
β (tinker init scans project) β
βββββββββββββββββββββββββββββββββββββββββββ
Design principles:
- Compose, don't reimplement β Shell out to usql/httpie/evans, don't rewrite them
- Contract is declarative β
tinker.toml, not a Go interface
- Auto-detect first, configure second β
tinker init should work for 80% of cases
- Cross-language by default β Works with any project that has a
.env and tinker.toml
Comparison
| Feature |
Laravel Tinker |
gore |
Tinker (this project) |
| Interactive DB session |
β
Eloquent |
β |
β
usql (raw SQL) |
| Call API endpoints |
β
HTTP client |
β |
β
httpie/curlie |
| Call gRPC services |
β |
β |
β
evans/grpcurl |
| Language-agnostic |
β PHP only |
β Go only |
β
Any project |
| Framework-agnostic |
β Laravel only |
β
|
β
|
| Execute project code |
β
Full PHP |
β
Go |
β οΈ tinker run (limited) |
| Auto-configuration |
β
|
β |
β
tinker init |
| Persistent state |
β
|
β οΈ Per eval |
β
DB session |
Roadmap
- OpenAPI spec parsing for API endpoint autocomplete
-
tinker api explore β interactive API explorer
- Custom command support from
[commands] section
- Connection testing (
tinker db ping, tinker api ping)
- Multi-environment support (
tinker --env staging db)
- Plugin system for custom modules
- Shell completion (bash, zsh, fish)
-
tinker db seed β run seed files
-
tinker db migrate β run migrations
- Docker integration β auto-detect docker-compose services
Contributing
Contributions are welcome! This project is in early development.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature)
- Commit your changes (
git commit -m 'Add amazing feature')
- Push to the branch (
git push origin feature/amazing-feature)
- Open a Pull Request
License
MIT License β see LICENSE for details.