Installation
Reshape is a monorepo containing two applications you will run side by side: the Laravel API in api/ and the Vue frontend in web/. This page walks you through installing both, configuring your environment, and setting up the local reshape.test domains with HTTPS.
Requirements
Before installing Reshape, make sure your machine has:
- PHP 8.5+ with the usual Laravel extensions
- Composer
- Node.js 18+ and npm
- SQLite (the default local database — MySQL and PostgreSQL work too)
Media Library Pro
Reshape uses Spatie Media Library Pro, which is installed from Spatie's private Composer registry. You need a license and credentials for satis.spatie.be — add them once with:
composer config http-basic.satis.spatie.be <your-email> <your-license-key>Installing the API
Clone the repository, then run the setup script from the api/ directory:
cd api
composer setupThe setup script (defined in composer.json) does the heavy lifting for you:
composer install- Copies
.env.exampleto.env(if one doesn't exist) php artisan key:generatephp artisan migrate --forcenpm install && npm run build(assets for the Filament admin panel)
Preparing reference data
Reshape ships with a db:prepare command that seeds everything the application needs to function — the permission catalog, roles, reaction types, countries, currencies, timezones, industries, contact methods, default themes, and plans:
php artisan db:prepareDon't skip this step
Roles and permissions are database records. Until db:prepare has run, no user can be assigned a role and most authorization checks will fail.
Demo data (optional)
If you'd like something to look at, seed the demo dataset — 25 companies with contacts, addresses, customers, and announcements, plus three ready-made accounts:
php artisan db:seed| Role | |
|---|---|
super_administrator@reshape.test | Super Administrator |
administrator@reshape.test | Administrator |
user@reshape.test | Super Administrator |
Since login is passwordless, you sign in to these accounts with a one-time code — with the default MAIL_MAILER=log the code is written to the Laravel log. See Development for the shortcut.
Installing the frontend
cd web
npm install
cp .env.example .envThe frontend's .env points at the API and defines which login options are shown:
VITE_BACKEND_URL=https://api.reshape.test
VITE_FRONTEND_URL=https://reshape.test
REVERB_APP_KEY=<same value as the API's REVERB_APP_KEY>
REVERB_HOST=api.reshape.test
REVERB_PORT=443
REVERB_SCHEME=https
# Show/hide social login buttons
VITE_OAUTH_GOOGLE=false
VITE_OAUTH_GITHUB=false
VITE_OAUTH_LINKEDIN=falseEnvironment configuration
The API's .env works out of the box with SQLite and the log mailer, but a few values deserve attention:
| Variable | What to set it to |
|---|---|
APP_URL | https://api.reshape.test |
FRONTEND_URL | https://reshape.test — used for CORS, redirects, and invitation links |
REVERB_APP_KEY / REVERB_APP_SECRET | Any random strings (e.g. openssl rand -hex 32); the key must match the frontend's REVERB_APP_KEY |
MAIL_MAILER | log for local development, or point it at Mailpit/SMTP to receive real emails |
AUTO_LOGIN_USER_EMAIL | Optional development helper — see Development |
One .env gotcha
.env.example defines FRONTEND_URL twice; the later http://localhost value wins. Make sure the effective value is https://reshape.test once you've set up local domains below.
Stripe
Billing uses Laravel Cashier. The Stripe keys are not present in .env.example, so add them yourself when you're ready to work on billing:
STRIPE_KEY=pk_test_...
STRIPE_SECRET=sk_test_...
STRIPE_WEBHOOK_SECRET=whsec_...OAuth providers
To enable social login, create OAuth apps with each provider and fill in the credentials:
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
GITHUB_CLIENT_ID=
GITHUB_CLIENT_SECRET=
LINKEDIN_CLIENT_ID=
LINKEDIN_CLIENT_SECRET=Then flip the matching VITE_OAUTH_* flags to true in web/.env so the buttons appear on the login page. The callback URL for each provider is https://reshape.test/oauth/callback/{provider}. See Authentication for details.
Local domains & HTTPS
Reshape's defaults assume the frontend lives at https://reshape.test and the API at https://api.reshape.test. Real domains and real HTTPS locally mean cookies, CORS, Sanctum, and websockets behave exactly like production — no localhost:3000 special cases.
The setup uses three small tools, adapted from this excellent write-up by François Liger:
- DNS — resolve
*.testto your machine - mkcert — generate locally-trusted TLS certificates
- Caddy — terminate HTTPS and proxy to your dev servers
macOS shortcut
If you use Laravel Herd, it already resolves *.test and can serve the API directly — cd api && herd link api.reshape && herd secure. You still need Caddy (or Herd's proxy feature) for the frontend on port 3000. The instructions below are the fully cross-platform path.
1. Point .test at your machine
brew install dnsmasq
# Resolve every .test domain to localhost
echo 'address=/test/127.0.0.1' >> "$(brew --prefix)/etc/dnsmasq.d/test.conf"
# Tell macOS to use dnsmasq for the .test TLD
sudo mkdir -p /etc/resolver
echo 'nameserver 127.0.0.1' | sudo tee /etc/resolver/test
sudo brew services start dnsmasqsudo apt install dnsmasq # or your distro's package manager
# Resolve every .test domain to localhost
echo 'address=/test/127.0.0.1' | sudo tee /etc/dnsmasq.d/test.conf
sudo systemctl restart dnsmasqWindows has no practical dnsmasq equivalent, so use the hosts file
instead. Open an elevated editor and add these lines to
C:\Windows\System32\drivers\etc\hosts:
127.0.0.1 reshape.test
127.0.0.1 api.reshape.testThe simple fallback
Reshape only needs two fixed hostnames, so the hosts-file approach shown for Windows works on macOS and Linux too (/etc/hosts). dnsmasq is only required if you want wildcard .test resolution — handy once you start adding more subdomains.
systemd-resolved
On Ubuntu-flavoured distros, systemd-resolved already listens on port 53. Either disable its stub listener (DNSStubListener=no in /etc/systemd/resolved.conf) or simply use the hosts-file fallback.
2. Generate trusted certificates
Install mkcert (brew install mkcert / apt install mkcert / choco install mkcert), then:
mkcert -install
mkdir -p ~/certs && cd ~/certs
mkcert "reshape.test" "*.reshape.test"This produces reshape.test+1.pem and reshape.test+1-key.pem, trusted by your browser because mkcert -install added a local CA to your system trust store.
3. Proxy with Caddy
Install Caddy (brew install caddy / apt install caddy / choco install caddy) and use this Caddyfile — on macOS at $(brew --prefix)/etc/Caddyfile, on Linux at /etc/caddy/Caddyfile:
reshape.test {
tls /Users/you/certs/reshape.test+1.pem /Users/you/certs/reshape.test+1-key.pem
reverse_proxy localhost:3000
}
api.reshape.test {
tls /Users/you/certs/reshape.test+1.pem /Users/you/certs/reshape.test+1-key.pem
# Reverb websockets
@reverb path /app/* /apps/*
reverse_proxy @reverb localhost:9000
reverse_proxy localhost:8000
}The @reverb matcher routes websocket traffic (/app/...) to the Reverb server on port 9000 while everything else goes to php artisan serve on port 8000 — which is why the frontend's .env can point Echo at api.reshape.test:443 over HTTPS.
Start Caddy:
brew services start caddysudo systemctl enable --now caddycaddy run --config C:\path\to\CaddyfileVerify
With both dev servers running (see Development), you should now be able to open:
https://reshape.test— the frontend, with a padlockhttps://api.reshape.test/up— the API health check

Next steps
Head over to Development to start the dev servers, log in, and learn the day-to-day workflow.