Skip to main content

Local Development

Overview​

This guide sets up a local development environment for iterating on backend and frontend code against deployed AWS infrastructure. By the end, the FastAPI backend is running on localhost:8000 with hot-reload, the React frontend is running on localhost:8080 with API requests proxied to the backend, and environment variables are configured to reach deployed Cognito, DynamoDB, and SQS resources.

When to Use This Guide​

Use this guide when:

  • A successful /ipa-deploy has completed and it is time to start writing application code
  • A new developer is onboarding and needs a working local environment
  • Switching between deployed environments (for example, from dev to stage) and the local environment variables need updating
  • Troubleshooting backend or frontend code against live AWS infrastructure without redeploying

Before You Start​

Before starting, confirm the following:

  • .env file exists with APP_NAMESPACE, APP_ENV, AWS_REGION, and AWS_ACCOUNT_ID set
  • At least one environment has been deployed with /ipa-deploy (the backend stack provides DynamoDB tables the local server connects to)
  • Python 3.12 is installed
  • uv is installed (Python package manager)
  • Node.js 22+ and npm are installed
  • AWS CLI is configured with credentials for the target account (via AWS_PROFILE or the default credential chain)

Before / Target State​

BeforeAfter
Deployed AWS infrastructure (DynamoDB, Cognito, SQS). No local servers running. Code changes require redeployment to test.FastAPI backend on localhost:8000 with auto-reload. React frontend on localhost:8080 with Vite proxy forwarding API requests. Code changes are reflected immediately without redeployment.

Steps​

1. Sync environment variables from deployed stacks​

To populate .env with the latest outputs from deployed CloudFormation stacks (Cognito, ECR, SQS), run from the project root:

make -f scripts/env.mk update-env

The command queries each deployed stack and writes the output values to .env. The terminal displays confirmation messages for each stack:

Writing OIDC configuration to .env...
Writing ECR configuration to .env...
Writing SQS configuration to .env...

To sync a single stack, use the specific target:

make -f scripts/env.mk update-env-cognito
make -f scripts/env.mk update-env-ecr
make -f scripts/env.mk update-env-sqs
note

The scripts/env.mk file is generated by /ipa-compose. If the file does not exist, run /ipa-compose first.

2. Start the backend​

To install Python dependencies, run from the project root:

cd app-lib && make sync

This runs uv sync --all-extras, installing all backend dependencies including FastAPI, uvicorn, PynamoDB, and boto3 into the local .venv.

To start the FastAPI development server with auto-reload, run from the project root:

make dev-backend

The backend starts on http://localhost:8000. The terminal displays:

INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO: Started reloader process

To verify the backend is running, open a new terminal and run:

curl http://localhost:8000/health

Expected output:

{"status":"ok"}

The interactive API documentation is available at http://localhost:8000/docs.

3. Start the frontend​

To install Node.js dependencies, run from the project root:

cd web-client && npm install

The postinstall script automatically copies the OIDC service worker to public/.

To start the Vite development server, run from the project root:

make dev-frontend

The frontend starts on http://localhost:8080. Vite is preconfigured to proxy /api, /health, and /version requests to the backend at http://localhost:8000. No additional proxy configuration is required.

Open http://localhost:8080 in a browser. The React application loads and API requests are forwarded to the local backend automatically.

4. Optional: Configure Cognito authentication locally​

By default, authentication is enabled (AUTH_ENABLED=true). For local development without a deployed Cognito stack, disable it by setting the environment variable before starting the backend:

export AUTH_ENABLED=false

To test with Cognito authentication enabled locally:

a. Confirm the OIDC values are present in .env by running the sync from Step 1, or verify that OIDC_ISSUER and OIDC_CLIENT_ID are set.

b. Create web-client/public/config.local.js to override the frontend OIDC configuration:

window.__CONFIG__ = {
...window.__CONFIG__,
OIDC_AUTHORITY: "https://cognito-idp.us-east-1.amazonaws.com/us-east-1_XXXXX",
OIDC_CLIENT_ID: "your-cognito-client-id",
OIDC_REDIRECT_URI: "http://localhost:8080/authentication/callback",
OIDC_END_SESSION_ENDPOINT: "https://your-domain.auth.us-east-1.amazoncognito.com/logout",
};

Replace the placeholder values with the actual OIDC values from .env. The config.local.js file is gitignored and loaded only on localhost.

warning

The Cognito User Pool must include http://localhost:8080/authentication/callback in its allowed callback URLs. If the callback URL is missing, add it to the Cognito stack parameters and redeploy with /ipa-deploy.

d. Restart both the backend and frontend for the changes to take effect.

Verification​

To confirm the local environment is fully operational:

  1. Verify the backend health endpoint:

    curl http://localhost:8000/health

    Expected: {"status":"ok"}

  2. Verify the backend version endpoint:

    curl http://localhost:8000/version

    Expected: {"version":"1.0.0","build":"dev"}

  3. Open http://localhost:8080 in a browser and confirm the React application loads.

  4. Confirm a round-trip API call by navigating to a data page (for example, the Passengers page) and verifying that data loads from the deployed DynamoDB table through the local backend.

Troubleshooting​

ProblemLikely CauseFix
curl: (7) Failed to connect to localhost port 8000Backend is not running or failed to startCheck the terminal for startup errors. Confirm Python 3.12 and uv are installed. Run cd app-lib && make sync to reinstall dependencies.
DynamoDB AccessDeniedException in backend logsAWS credentials are missing or the region does not match the deployed stacksConfirm AWS_REGION in .env matches the deployment region. Verify AWS CLI credentials with aws sts get-caller-identity.
CORS errors in the browser consoleFrontend is not using the Vite proxy (requests going directly to the backend)Confirm API_BASE_URL is empty in web-client/public/config.js. The Vite proxy handles routing when API_BASE_URL is not set.
Cognito redirects to an error page after loginlocalhost:8080 is not in the allowed callback URLs for the Cognito User PoolAdd http://localhost:8080/authentication/callback to the Cognito stack's CallbackURLs parameter and redeploy.
Port 8000 or 8080 already in useAnother process is listening on the required portIdentify the process with lsof -i :8000 or lsof -i :8080 and stop it before starting the development servers.

Next Steps​

  • Notebook Development — Prototype and test with Jupyter notebooks connected to deployed resources
  • Regenerate API client — With the backend running, run cd web-client && npm run codegen to update the TypeScript API client from the OpenAPI schema
  • Backend developer docs — See the app-lib/ CLAUDE.md for backend architecture, feature structure, and testing conventions
  • Frontend developer docs — See the web-client/ CLAUDE.md for frontend architecture, component placement, and API layer conventions
  • Tear down the deployment — Run /ipa-destroy to remove deployed infrastructure when no longer needed