A start-to-finish walkthrough for running the TricklePay frontend on your own machine: what to install, what every environment variable means and where its value comes from, how to check the setup actually works, and what the common first-run failures look like.
If you only need the variable table, see Configuration in the README. If you are setting up to contribute a change, read this first and then CONTRIBUTING.md for the branch and PR workflow.
- 1. Prerequisites
- 2. Clone and install
- 3. Create your env file
- 4. Fill in each variable
- 5. Choose your ports
- 6. Set up Freighter
- 7. Run the app
- 8. Verify the setup
- 9. Common setup failures
- 10. Day-to-day commands
| Requirement | Version | Why |
|---|---|---|
| Node.js | >=20.0.0 (20 LTS or newer) |
Next.js 15, React 19, and the Tailwind v4 build tooling rely on Node 20 runtime features and module resolution. Node 18 fails during install or compilation. |
| npm | >=10.0.0 |
Ships with Node 20. |
| Git | any recent version | Cloning the repo. |
| Freighter browser extension | latest | The only supported wallet. Needed to connect, sign, and submit — but not needed to browse a stream page read-only. |
A running tricklepay-backend |
— | Serves every list and detail view. Without it the app loads but every stream list errors. |
| A deployed stream contract id | — | Required at startup; the app refuses to boot without one (see below). |
Check your versions:
node --version # v20.x or newer
npm --version # 10.x or newerThe backend and contract are the two pieces that come from outside this repo. Everything else is self-contained.
git clone https://github.com/TricklePay/tricklepay-frontend.git
cd tricklepay-frontend
npm installnpm install also installs the Playwright test runner, but not its browser
binaries — those are a separate download, only needed if you plan to run the
end-to-end suite (see §10).
cp .env.example .env.localOn Windows PowerShell, use Copy-Item .env.example .env.local.
Which filename? Next.js loads .env.local in preference to .env, and
both are ignored by .gitignore, so either keeps your values out of Git.
Prefer .env.local for machine-specific values — if you also keep a shared
.env, .env.local wins on any key the two have in common, which is exactly
the override you want.
Important
NEXT_PUBLIC_* values are inlined into the client bundle at build time, not
read at runtime. Editing the env file while the dev server is running has no
effect until you restart it (Ctrl+C, then npm run dev again), and a
production deployment needs a full npm run build, not just a restart.
| Variable | Required | Default | Where the value comes from |
|---|---|---|---|
NEXT_PUBLIC_CONTRACT_ID |
Yes | none | The deployed stream contract. A 56-character Stellar contract address starting with C — from your own deploy of tricklepay-contracts, or from whoever runs the shared testnet deployment. |
NEXT_PUBLIC_API_URL |
No | http://localhost:3000 |
Base URL of your running tricklepay-backend. |
NEXT_PUBLIC_NETWORK |
No | testnet |
testnet or mainnet. Keep it on testnet for development — it must match the network selected in Freighter. |
NEXT_PUBLIC_RPC_URL |
No | https://soroban-testnet.stellar.org |
Soroban RPC endpoint used to submit signed transactions. The public endpoint is fine; override it only if you run your own node or hit rate limits. |
NEXT_PUBLIC_API_TIMEOUT_MS |
No | 10000 |
How long a backend read may run before it is aborted, in milliseconds. Raise it if your backend is slow to start or lives behind a slow link; 0 disables the timeout. Invalid values are rejected at startup. |
A filled-in .env.local for typical local work:
NEXT_PUBLIC_API_URL=http://localhost:3000
NEXT_PUBLIC_NETWORK=testnet
NEXT_PUBLIC_RPC_URL=https://soroban-testnet.stellar.org
NEXT_PUBLIC_API_TIMEOUT_MS=10000
NEXT_PUBLIC_CONTRACT_ID=CA3D5KRYM6CB7OWQ6TWYRR3Z4T7GNZLKERYNZGGA5SOAOPIFY6YQGAXEThe contract id is validated at startup. lib/config.ts checks it as the
module loads, so a missing or malformed value stops the app immediately with a
plain-language error rather than surfacing as an opaque SDK failure at the
first transaction:
Configuration error: NEXT_PUBLIC_CONTRACT_ID is not set. Add it to your .env file (it starts with C).
The network passphrase is derived from NEXT_PUBLIC_NETWORK and is not
configurable on its own — there is no variable to set for it.
next dev listens on 3000, and tricklepay-backend also defaults to
3000. Running both with their defaults means one of them fails to bind, so
pick one of these:
# Option A — backend keeps 3000, frontend moves (nothing to change in .env.local)
npm run dev -- --port 3001 # then open http://localhost:3001# Option B — frontend keeps 3000, backend moves
# .env.local:
NEXT_PUBLIC_API_URL=http://localhost:4000Option A is the smaller change: NEXT_PUBLIC_API_URL already defaults to
http://localhost:3000, so the frontend finds the backend with no config at
all. Whichever you choose, the two ports must differ and NEXT_PUBLIC_API_URL
must name the backend's.
The Playwright end-to-end suite is unaffected — it starts its own dev server on 3100 with its own env values and stubs the network, so it neither needs nor touches your backend.
- Install the extension from freighter.app.
- Create or import an account.
- Switch the network selector to Test Net — it must match
NEXT_PUBLIC_NETWORK. A mismatch is caught before signing and shown as a banner; the app refuses to build a transaction that would fail in the wallet anyway. - Fund the account. A brand-new testnet account holds nothing, and creating a stream costs both fees and the streamed tokens. Use the Stellar Laboratory account creator or Friendbot.
Browsing and reading streams works without any of this; only signing does not.
npm run devOpen the URL the terminal prints (http://localhost:3000, or 3001 if you moved it) and click Connect wallet.
Work down this list — each step isolates a different piece, so the first one that fails tells you where the problem is.
npm run typecheck # TypeScript compiles
npm run lint # ESLint passes
npm run test # Vitest unit suite passesThese three need no backend, no wallet, and no env file: the unit suite injects
its own NEXT_PUBLIC_CONTRACT_ID (see vitest.config.mts), which is why it
passes even before you have a real contract id.
Then, in the browser:
- The page renders rather than showing a configuration error →
NEXT_PUBLIC_CONTRACT_IDis set and well-formed. - A stream list loads (even an empty "No streams yet.") without an error
banner →
NEXT_PUBLIC_API_URLpoints at a reachable backend. - Connect wallet succeeds and shows your address → Freighter is installed and unlocked.
- No network-mismatch banner → Freighter's network matches
NEXT_PUBLIC_NETWORK. - Create stream reaches the signing prompt → the contract id and RPC endpoint are usable.
The env file is missing, is named something Next.js does not load, or the key
is empty. Confirm the file is .env.local (or .env) in the repository root,
then restart the dev server — this value is read at build time, so a running
server will not pick it up.
The value is present but malformed. A contract address is 56 characters and
starts with C; a G... account address or a truncated paste both trigger
this. Copy the id again from your deploy output.
Something else — most often tricklepay-backend — already holds the port. See
§5.
The backend accepted the connection but did not answer in time. Usually it is
starting up, or is genuinely unreachable; if it is merely slow, raise
NEXT_PUBLIC_API_TIMEOUT_MS (for example to 30000) and restart the dev
server. Setting it to 0 removes the budget altogether, at the cost of a
request that can hang indefinitely.
The backend is not running, or NEXT_PUBLIC_API_URL points somewhere else.
Start the backend and confirm the URL, including the port and the absence of a
trailing path.
Freighter is on a different network from NEXT_PUBLIC_NETWORK. Switch the
extension to Test Net, or change the variable and restart the server.
NEXT_PUBLIC_* values are compiled into the bundle. Restart npm run dev; for
a built app, re-run npm run build. A stale build serving an old contract id
shows up as transactions hitting the wrong contract.
Check node --version. Node 18 and older cannot build this project.
| Command | What it does |
|---|---|
npm run dev |
Dev server with hot reload. Add -- --port 3001 to move it. |
npm run build |
Production build — the only way to pick up changed NEXT_PUBLIC_* values for npm start. |
npm start |
Serves the production build. |
npm run lint |
ESLint. |
npm run typecheck |
tsc --noEmit. |
npm run test |
Vitest unit suite (lib/, components/), one pass. |
npm run test:watch |
Vitest in watch mode. |
npm run test:e2e |
Playwright end-to-end suite. Run npx playwright install chromium once first; it starts its own dev server on port 3100 and stubs all network traffic, so no backend or wallet is needed. |
- README — Configuration — the variable table on its own.
- README — Troubleshooting — runtime issues beyond first-run setup.
- docs/api-contract.md — what the backend and contract surfaces are expected to return.
- CONTRIBUTING.md — coding standards, testing strategy, and the pull request process.