Tired of bouncing between registrars, tracking domain renewals in spreadsheets, and copy-pasting secrets into .env files?
π― indietool is a CLI tool for indie builders that helps you
- π Hunt domain names across 50+ TLDs β in seconds
- ποΈ Track expiries across registrars like Cloudflare & Porkbun
- βοΈ Manage DNS records across providers with auto-detection
- π Securely store API keys & secrets β OS keyring or SSH-key encrypted
No dashboards. No vendor lock-in. Just you and your terminal.
# macOS/Linux (recommended)
go install github.com/indietool/cli@latest# Check domain availability
indietool domain explore myapp
# Save a test API key (auto-creates encryption key)
indietool secret set stripe-key "sk_test_..." --note "Stripe test key"
# Manage DNS records with automatic provider detection
indietool dns list example.com# Check which domains are available
indietool domain explore myproject --tlds dev,com,ai
# Set up DNS records for your new domain
indietool dns set myproject.dev @ A 192.168.1.100
indietool dns set myproject.dev www CNAME myproject.dev
indietool dns set myproject.dev api A 192.168.1.101
# Store your API keys securely (auto-creates encryption key)
indietool secret set openai-key "sk-..." --note "OpenAI API key"
indietool secret set stripe-key "sk_test_..." --note "Stripe test key"
# Organize secrets by project using custom databases
indietool secret set api-key@myproject "key123" --note "Project-specific key"# Check domain expiry before renewal
indietool domains list --provider cloudflare
# Verify DNS configuration before going live
indietool dns list myproject.com --wide
# Clean up old DNS records
indietool dns delete myproject.com old-api A
# Update production DNS records
indietool dns set myproject.com @ A 203.0.113.10
indietool dns set myproject.com www CNAME myproject.com
# Export secrets for deployment
export OPENAI_KEY=$(indietool secret get openai-key -S)Problem: Manually checking domain names is slow and painful.
Solution: indietool domain explore checks 50+ TLDs in seconds.
indietool domain explore awesomeprojectDOMAIN STATUS TLD EXPIRY
awesomeproject.ai Available ai -
awesomeproject.dev Available dev -
awesomeproject.com Taken com 2026-07-06
...
50 domains checked: 45 available, 5 taken
Filter by specific TLDs:
indietool domain explore awesomeproject --tlds ai,dev,io,shOr pass a TLD list from file:
indietool domain explore myproject --tlds @tldfileKnow the exact domain you're targeting?
indietool domain search awesomeproject.ioProblem: Domains expire. You donβt want surprises. Solution: View all domains across registrars in one simple table.
First, connect your registrar(s):
# Cloudflare
indietool config add provider cloudflare \
--account-id YOUR_ACCOUNT_ID \
--api-token YOUR_TOKEN \
--email your@email.com
# Porkbun
indietool config add provider porkbun \
--api-key YOUR_KEY \
--api-secret YOUR_SECRET
# The Little Host (DNS only)
indietool config add provider thelittlehost --api-key tlh_YOUR_API_KEYThen list your domains:
indietool domains listNAME PROVIDER STATUS EXPIRES AUTO-RENEW AGE
myawesomeapp.com cloudflare healthy 8mo Yes 2y
sideproject.ai cloudflare healthy 1y Yes 1y
Need more info?
indietool domains list --wideNAME PROVIDER STATUS EXPIRES AUTO-RENEW AGE NAMESERVERS COST UPDATED
myawesomeapp.com cloudflare healthy 8mo Yes 2y fred.ns.cloudflare.com,pam.ns.cl... N/A 2y
sideproject.ai cloudflare healthy 1y Yes 1y fred.ns.cloudflare.com,pam.ns.cl... N/A 1y
Problem: Managing DNS records across different providers is tedious and error-prone.
Solution: indietool dns automatically detects your DNS provider and lets you list and update records from the command line.
# Auto-detect provider and list records
indietool dns list example.comDNS Provider: cloudflare
TYPE NAME CONTENT
A βοΈ@ 192.168.1.1
A www 192.168.1.2
CNAME βοΈapi example.com
MX @ 10 mail.example.com
Note: βοΈ indicates Cloudflare proxied records, available only with the Cloudflare provider, for domains hosted on Cloudflare
indietool dns list example.com --wideTYPE NAME CONTENT TTL PRIORITY ID
A βοΈ@ 192.168.1.1 300 abc123
A www 192.168.1.2 300 def456
CNAME βοΈapi example.com 300 ghi789
MX @ mail.example.com 300 10 jkl012
# Add an A record
indietool dns set example.com www A 192.168.1.100
# Add MX record with priority
indietool dns set example.com @ MX "10 mail.example.com" --priority 10
# Add TXT record for domain verification
indietool dns set example.com @ TXT "v=spf1 include:_spf.google.com ~all"# Delete specific record by name and type
indietool dns delete example.com www A
# Delete all records for a name (with confirmation)
indietool dns delete example.com api
# Delete specific record by ID (when multiple records have same name)
indietool dns delete example.com test --id abc123
# Delete without confirmation
indietool dns delete example.com www A --force
# Delete root domain record
indietool dns delete example.com @ MX
# Combine filters for precision
indietool dns delete example.com api --type CNAME --id def456# Use specific provider instead of auto-detection
indietool dns list example.com --provider cloudflare
indietool dns set example.com api A 192.168.1.50 --provider porkbun
indietool dns delete example.com old-record A --provider namecheap- β Cloudflare - Full CRUD operations with proxy status indicators
- β Porkbun - Complete DNS record management (list, set, delete)
- β Namecheap - Full CRUD support with batch operations
- β The Little Host - Full DNS record management
indietool automatically detects your DNS provider by checking nameservers:
- No need to specify
--providerin most cases - Seamlessly works across different providers
- Falls back to manual provider selection if needed
Problem: Secrets are either insecure or annoying to manage.
Solution: indietool secrets encrypts secrets using your OS keyring β no cloud, no sync, no complicated setup to manage.
| Component | Backend | Stored At | Encrypted |
|---|---|---|---|
| Secrets Database | both | ~/.config/indietool/secrets/ |
β |
| Encryption Key | keyring | OS Keyring (Keychain, gnome-keyring) |
β |
| Encryption Key | age-ssh | ~/.config/indietool/keys/db-key-<database>.age |
β |
indietool supports two backends for storing the database encryption key:
- keyring (default) β uses your OS keyring. Works well for desktop sessions.
- age-ssh (recommended for servers / SSH sessions) β encrypts the key with your SSH public key and stores it as a file. Decryption uses your SSH private key or agent.
# Explicit initialization with age-ssh (recommended for remote hosts)
indietool secrets init --backend age-ssh
# Specify a custom SSH key pair
indietool secrets init --backend age-ssh \
--ssh-public-key ~/.ssh/id_rsa.pub \
--ssh-private-key ~/.ssh/id_rsa
# Explicit initialization using the OS keyring
indietool secrets init --backend keyringIf indietool detects that the keyring is unavailable (e.g. in an SSH session), it will guide you through selecting an SSH key automatically on first use.
No setup required! The first time you store a secret, indietool automatically creates an encryption key.
indietool secret set stripe-key "sk_test_..." --note "Stripe test key"
β Auto-generated encryption key for database 'default'
β Secret 'stripe-key' stored successfullyUse the key@database format to organize secrets by project or environment:
# Store in custom databases
indietool secret set api-key@production "prod_key_123"
indietool secret set api-key@staging "staging_key_456"
indietool secret set db-password@myproject "secret123"
# Retrieve from specific database
indietool secret get api-key@production -S# Safe output (masked)
indietool secret get stripe-key
# Show actual value (use -S or --show)
indietool secret get stripe-key -S# List secrets in default database
indietool secret list
# List secrets in specific database
indietool secret list @production
indietool secret list @stagingList all your secret databases:
indietool secrets db listAvailable secrets databases:
default (default)
production
staging
myproject
Delete a database and all its secrets:
# Interactive confirmation
indietool secrets db delete staging
# Force delete without confirmation
indietool secrets db delete staging --forceexport STRIPE_KEY=$(indietool secret get stripe-key -S)| Provider | Domains | DNS | Secrets |
|---|---|---|---|
| Cloudflare | β | β | β |
| Porkbun | β | β | β |
| Namecheap | β | β | β |
| GoDaddy | β | β | β |
| The Little Host | β | β | β |
| Local | β | β | β |
Legend:
- β Full support
- π§ In development
- β Not supported
Notes:
- Domains: Domain registration management, expiry tracking, nameserver updates
- DNS: DNS record management (list, create, update, delete) with ID-based targeting
- Secrets: Local encrypted secret storage (OS keyring or age-ssh backend)
Encrypted locally at ~/.config/indietool/secrets/. The encryption key is stored in your OS keyring (default) or as an age-encrypted file at ~/.config/indietool/keys/ when using the age-ssh backend.
Secrets are useless without your encryption key. With the default keyring backend, start fresh on the new machine. With the age-ssh backend, your key file (~/.config/indietool/keys/) and SSH private key are both required β back up the keys directory if you need portability.
Not yet β currently macOS and Linux only. Windows support is planned.
- Ensure your keyring (Keychain or gnome-keyring) is unlocked
- Check file permissions on
~/.config/indietool/secrets/
GUI keyrings like GNOME Keyring require a graphical session to unlock, so they fail over SSH. Use the age-ssh backend instead:
indietool secrets init --backend age-sshThis encrypts the database key with your SSH public key. To decrypt over SSH, connect with agent forwarding enabled:
ssh -A yourserver.example.com
# or add 'ForwardAgent yes' to your ~/.ssh/config- Check file permissions on
~/.config/indietool - Ensure your user has write access to the config directory
- Double check key/secret pair
- Some registrars require IP allowlisting or scopes
- β No Windows support (yet)
- π§© Registrar support: Cloudflare, Porkbun, Namecheap, GoDaddy
- βοΈ DNS management: GoDaddy implementation in progress
- π» CLI only β no web UI or GUI planned
- π Secrets not synced across machines (by design β use age-ssh for cross-host access via SSH agent forwarding)
Stop wasting time in control panels and spreadsheets.
Let indietool handle the busywork β so you can focus on building.