vblinden / stackd
Local database and service manager for macOS — MySQL, MariaDB, PostgreSQL, Valkey, Mailpit, Meilisearch, and MinIO for Laravel and Next.js development
Requires
- php: ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0
- ext-curl: *
- ext-json: *
Requires (Dev)
- laravel-zero/framework: ^12.0.2
- laravel/pint: ^1.25.1
- laravel/prompts: ^0.3.21
- mockery/mockery: ^1.6.12
- nunomaduro/termwind: ^2.4
- pestphp/pest: ^3.8.4|^4.1.2
Suggests
- ext-pcntl: Needed for animated spinners in Laravel Prompts
Provides
None
Conflicts
None
Replaces
None
README
Local database and service manager for macOS.
Create global named instances of MySQL, MariaDB, PostgreSQL, Valkey, Mailpit, Meilisearch, and MinIO — then connect any Laravel or Next.js project to them. Built to sit alongside Laravel Valet. Native binaries by default; official Docker images if you want them.
Why stackd?
- Services — MySQL, MariaDB, PostgreSQL, Valkey, Mailpit, Meilisearch, and MinIO
- Global instances — one MySQL for all your apps, not a container per project
- Laravel and Next.js —
stackd envoverwrites your.envfor every installed service (and uses your project folder as the DB name) - No Docker required — downloads (or builds) native binaries on demand
- Optional Docker —
stackd runtime dockerruns new instances from official images instead - macOS native — binds to
127.0.0.1, optional LaunchAgent start-at-login - TablePlus & browser ready —
stackd openlaunches the right client
Requirements
- macOS
- PHP 8.2–8.5
- Xcode Command Line Tools (Valkey / MariaDB compile, native runtime only)
cmakeand OpenSSL for MariaDB (stackd can install these via Homebrew when prompted)- Docker Desktop only if you switch the runtime to Docker
- Avoid Homebrew MySQL/Postgres/Redis on the same ports —
stackd createdetects them and can uninstall
Installation
Via Composer (recommended)
composer global require vblinden/stackd
This installs the prebuilt PHAR from the package (builds/stackd). Make sure Composer's global bin directory is on your PATH.
PHAR
curl -fsSL https://raw.githubusercontent.com/vblinden/stackd/master/bin/install.sh | bash
Or install manually:
curl -fsSL https://github.com/vblinden/stackd/releases/latest/download/stackd -o stackd chmod +x stackd sudo mv stackd /usr/local/bin/stackd stackd doctor
Default credentials
| Service | Username | Password |
|---|---|---|
| MySQL / MariaDB | root |
(empty) |
| PostgreSQL | laravel |
(empty) |
| MinIO | stackd |
secretkey |
| Meilisearch | — | random master key (shown on create) |
Quick start
# Interactive picker stackd create # Or create directly stackd create mysql stackd create valkey stackd create mailpit # From a Laravel or Next.js project root — writes .env for all installed stackd services stackd env stackd env --show # print only # Open clients stackd open mysql # TablePlus stackd open mailpit # Browser # Check health stackd doctor stackd status
create starts the instance immediately and can optionally add it to start-at-login.
Next.js apps get Prisma/Drizzle DATABASE_URL, REDIS_URL, and SMTP/EMAIL_* keys (written to .env, or .env.local if that is the only env file). Laravel apps still get DB_* / MAIL_*.
Runtime (native or Docker)
Native binaries are the default. Set the default for new instances once:
stackd runtime # show: native stackd runtime docker # new creates use official images stackd runtime native # switch back stackd create mysql # uses the current default stackd create mysql --docker stackd create valkey --native
Existing instances keep the runtime they were created with. Status, list, and the home screen show native or docker on each instance.
| Service | Docker image |
|---|---|
| MySQL | mysql:8.4 / mysql:8.0 |
| MariaDB | mariadb:11.4 |
| PostgreSQL | postgres:18 |
| Valkey | valkey/valkey:8 |
| Mailpit | axllent/mailpit |
| Meilisearch | getmeili/meilisearch:v1.51 |
| MinIO | minio/minio |
Docker instances still bind 127.0.0.1, use the same ports and credentials, and store data under ~/.stackd/instances/…. There is no host Unix socket — connect with 127.0.0.1 and the instance port (mysql -h 127.0.0.1 -P 3306 -u root). stackd start, stop, logs, env, open, and delete work the same way. Autostart uses --restart unless-stopped so containers come back when Docker Desktop starts.
Native data directories are not migrated into Docker (on-disk layouts differ). Create a new docker instance, or keep the native one. Docker Desktop must be running for docker creates and starts.
Commands
| Command | Description |
|---|---|
stackd create / add |
Create (and start) a service instance |
stackd start [service] [name] |
Start an instance, or all instances when no service is given |
stackd stop [service] [name] |
Stop an instance, or all instances when no service is given |
stackd restart <service> [name] |
Restart an instance |
stackd status |
Show all instances |
stackd list |
List instances as a table |
stackd delete / remove / uninstall |
Delete an instance and its data |
stackd env [service] [name] |
Write .env keys for Laravel or Next.js projects |
stackd env --show |
Print variables instead of writing |
stackd open <service> [name] |
Open TablePlus or the web UI |
stackd logs <service> [name] |
Tail instance logs |
stackd doctor |
Diagnose install & dependencies |
stackd autostart … |
Manage LaunchAgent start-at-login |
stackd runtime [native|docker] |
Show or set the default runtime for new instances |
Run stackd with no arguments for the home screen (running services + command list).
How it works
Instances live under ~/.stackd/:
~/.stackd/
├── registry.json # Instance metadata
├── config.json # Default runtime (native or docker)
├── autostart.json # Start-at-login entries
├── binaries/ # Downloaded / built binaries
├── instances/
│ └── mysql/default/
│ ├── data/
│ ├── logs/
│ └── …
└── logs/
Binaries are fetched the first time you create a service. MariaDB and Valkey compile locally; other services use official release archives.
Services are tuned for local macOS use: smaller memory footprints, less aggressive disk sync, and background process priority so idle instances are easier on battery. Restart existing instances (stackd restart <service>) to pick up the new settings.
Building a PHAR
composer install php stackd app:build stackd --build-version=v1.2.0 php builds/stackd --version
Commit builds/stackd before tagging. Packagist serves that PHAR via composer global require; tagged releases (v*) also attach it to the GitHub release.
Changelog
See CHANGELOG.md and GitHub Releases.
Contributing
Issues and pull requests are welcome on GitHub.