A minimal full‑stack demo that incorporates Plaid. See recent transactions, net income over the last month, account balances, and some of the edge cases Plaid can create in your apps.
This workshop will be a walkthrough of a reference design. The focus is on how the pieces fit together: the architecture and the integration points with Plaid.
- Use realistic data flows to reason about product ideas in personal finance, lending, or budgeting.
- Show a clean separation between client/auth, API, Plaid integration, and persistence.
- Keep infra light so we can focus on the integration: CSV files instead of a full database.
- Client (Vite + React)
- Auth via Auth0; acquires an access token for API calls.
- Renders a simple dashboard for accounts and a monthly in/out summary.
- Server (Express)
- CORS + JSON + health check.
- Auth middleware with Auth0 JWT validation, then enriches the request with a
userRecord. - Routes for Plaid flows and webhook ingestion.
- CSV‑backed persistence for users, items, accounts, transactions, and webhook logs. ( yes, yes, I know not a real DB but we all have our opinions on DB providers so this felt like the safest bet lol )
- What happens: Client asks Server for a Link token → Server creates a token with Plaid → returns token → Client opens Link.
- Code to explore/implement live:
- Server route:
server/src/routes/plaid.ts→POST /plaid/link/token/create - Plaid wrapper:
server/src/plaid/PlaidClient.ts→createLinkToken - Client:
client/src/components/Dashboard.tsx→createLink
- Server route:
- Docs:
- Link token flow: https://plaid.com/docs/link/token-flow/
- API: https://plaid.com/docs/api/tokens/#linktokencreate
- Link Web SDK: https://plaid.com/docs/link/web/
- What happens: After Link success the client receives a
public_token→ Server exchanges it with Plaid for anaccess_token→ Server stores token for the user. - Code to explore/implement live:
- Server route:
server/src/routes/plaid.ts→POST /plaid/item/public_token/exchange - Plaid wrapper:
server/src/plaid/PlaidClient.ts→exchangePublicToken - Persistence:
server/src/db/csvDb.ts→createPlaidItem
- Server route:
- Docs:
- What happens: Client requests accounts/transactions → Server looks up the user’s
access_token→ Server calls Plaid and returns mapped data to the client. - Code to explore/implement live:
- Server routes:
GET /plaid/accounts,GET /plaid/transactions,GET /plaid/summaryinserver/src/routes/plaid.ts - Plaid wrapper:
server/src/plaid/PlaidClient.ts→getItem,getAccounts,getTransactions - Client data load:
client/src/components/Dashboard.tsx→refresh
- Server routes:
- Docs:
- Accounts Get: https://plaid.com/docs/api/accounts/#accountsget
- Transactions Get: https://plaid.com/docs/api/products/transactions/#transactionsget
- Item Get: https://plaid.com/docs/api/items/#itemget
- Frontend
- VITE_API_BASE_URL
- API Route to prepend to requests
- VITE_AUTH0_DOMAIN
- VITE_AUTH0_CLIENT_ID
- VITE_AUTH0_AUDIENCE
- VITE_API_BASE_URL
- Backend
- PLAID_BASE_URL
- PLAID_CLIENT_ID
- PLAID_SECRET
- AUTH0_DOMAIN
- AUTH0_AUDIENCE
- User logs in on the client using Auth0.
- Client requests include a Bearer token.
- Server validates JWT (
checkJwt) and attaches auserRecord(attachUser). - Protected routes (under
/plaid) use the attached user to perform operations and persist results.
src/plaid/PlaidClient.ts- Thin wrapper around Plaid API:
createLinkToken,exchangePublicToken,getAccounts,getTransactions,syncTransactions. - Configured via
src/env.tswithPLAID_*variables.
- Thin wrapper around Plaid API:
src/routes/plaid.tsPOST /plaid/link/token/create: creates a Link token for the authenticated user.POST /plaid/item/public_token/exchange: exchanges apublic_tokenfor anaccess_token, persists the item, fetches accounts, and stores them.GET /plaid/accounts: returns items with associated accounts for the authenticated user.GET /plaid/transactions: scaffold for later—discusses how to fetch or sync and map into local storage.
src/routes/webhook.tsPOST /plaid/webhook: receives Plaid webhooks and appends to a CSV log for inspection.
server/src/db/csvDb.tsmanages files inserver/DB/:users.csv,plaid_items.csv,accounts.csv,transactions.csv,webhook_logs.csv.
- Provides utilities to:
- Initialize CSV files, append and write rows.
- Find or create users by Auth0 subject.
- Create Plaid items and add accounts per item.
- List items + accounts for a user, and append webhook logs.
client/src/main.tsx– Auth0 provider wiring from.envvaluessrc/App.tsx– Login/logout + rendersDashboardsrc/components/Dashboard.tsx– Authenticated API calls; accounts and transaction summary UI
server/src/index.ts– App bootstrap, CORS/JSON, health, route mounting, error handlersrc/auth.ts– JWT validation and request user attachment via CSV storesrc/env.ts– Environment variables (Auth0, Plaid, CORS)src/routes/plaid.ts– Link token, token exchange, accounts, transactions scaffoldsrc/routes/webhook.ts– Webhook ingestion and loggingsrc/plaid/PlaidClient.ts– Plaid API wrappersrc/db/csvDb.ts– CSV persistence helperssrc/middleware/errorHandler.ts– Fallback error handling
shared/src/index.ts– Shared types:User,Account,Transaction
- Architecture tour: client → server → Plaid → CSV store
- Auth and request lifecycle on the server
- Plaid: Link token creation and token exchange
- Persisting items and accounts; reading them back for the dashboard
- Webhooks: receiving, logging, and how to act on events
- Transactions strategy: on‑demand vs sync, mapping and categorization (design discussion)
- Extensibility and production hardening
- Store Plaid
access_tokensecurely; consider encryption and key management. - Replace CSV with a real database and a proper schema with migrations.
- Verify webhook signatures and handle retries/idempotency.
- Rate limits, pagination/sync cursors, and backfills.
- Observability: structured logs and metrics for Plaid calls and webhook processing.
- Frontend: integrate Plaid Link widget; robust error states and retries.
- Prereq: Node.js 18+
- Env files: create
server/.envandclient/.envwith Auth0 and Plaid sandbox values. - Install deps:
cd server && npm installcd ../client && npm install
- Start:
- Server:
cd server && npm run dev→ http://localhost:4000- I made a simple set of scripts for production credentials so command is
npm run prod
- I made a simple set of scripts for production credentials so command is
- Client:
cd client && npm run dev→ http://localhost:3000
- Server:
- Health check:
GET /health→{ ok: true }
- Error States
- Re-Linking Accounts
- Webhooks
- https://plaid.com/docs/api/webhooks/#configuring-webhooks
- NOTE: To use Plaid webhooks, a public url accessible from third-party machines via the web is necessary
- My go-to for enabling this is ngrok
- creates a custom public url accessible via HTTPS
- Mobile
- Unlinking Accounts
- Extra Functionality


