A production-ready natal chart and interpretation app built with Next.js.
Powered by FreeAstroAPI
Live Demo: open-chart.vercel.app
Use the Deploy with Vercel button above to clone and deploy instantly.
During setup, add this required environment variable:
FREE_ASTRO_API_KEY= your API key from freeastroapi.com
The app proxies all upstream calls server-side, so the key never ships to the browser bundle.
Open Chart is a minimalist, editorial-style natal report app with:
- City autocomplete and strict birth-data validation
- Live natal calculation from FreeAstroAPI
- SVG natal wheel rendering
- Structured report sections for ASC/MC, planets, aspects, and thematic interpretation
- Interactive chart behavior (hover insight, aspect selection, visual highlighting)
The stack is designed for production deployment with strict typing, runtime schema validation, and server-only API access.
Minimalist white-background report interface with a large Natal Wheel on the left and a structured right rail showing identity/birth metadata (date, time, timezone, location, system, UTC, Julian values), followed by compact Planet positions and Objects tables. A contextual hover panel appears over the chart (example: Moon in Capricorn) with concise sign/house interpretation text, matching the app's editorial black/gray visual system with thin separators and no heavy card chrome.
Tabular aspect analysis with columns for Aspect, Type, Phase, Orb, Strength, and Class (Major/Minor), designed for quick astrologer-grade scanning and comparison.
- Next.js App Router architecture
- TypeScript strict mode
- Tailwind CSS minimalist black/white design system
- React Hook Form + Zod input validation
- Route Handler proxies for geo search, natal calculation, and chart SVG
- Runtime response validation with Zod before render
- Aspect dynamics table with phase (Applying/Separating/Unknown)
- Right-side summary rail for quick chart data reference
- Unit tests for payload transforms, schemas, and formatters
- Framework: Next.js 14+ (App Router)
- Language: TypeScript (strict)
- Styling: Tailwind CSS
- Forms: React Hook Form + Zod
- Validation: Zod schemas for requests and responses
- Testing: Vitest
- Linting/Formatting: ESLint + Prettier
This app uses FreeAstroAPI docs contracts:
- Natal:
https://www.freeastroapi.com/docs/western/natal - Geo search:
https://www.freeastroapi.com/docs/geo/search - Chart SVG:
https://www.freeastroapi.com/docs/western/chart-svg
Upstream base URL used in server code:
https://astro-api-1qnc.onrender.com/api/v1
Authentication header sent server-side only:
x-api-key: FREE_ASTRO_API_KEY
git clone https://github.com/GabrielRw/open-chart.git
cd open-chartnpm installCreate .env.local:
FREE_ASTRO_API_KEY=your_freeastroapi_key_hereA template is included as .env.example.
npm run devOpen http://localhost:3000.
npm run dev— start local development servernpm run build— production buildnpm run start— run production servernpm run lint— run ESLintnpm run test -- --run— run unit tests once
GET /api/geo/search?q=...&limit=...- Proxies upstream geo search
- Normalizes city results
POST /api/natal/calculate- Validates payload with Zod
- Calls upstream natal endpoint (
include_minor=true)
POST /api/natal/chart-svg- Validates payload + chart config
- Calls upstream natal chart SVG endpoint
Error handling includes mapped responses for validation, auth, rate-limit, timeout, network, and upstream schema mismatch scenarios.
The app sends this natal structure (validated):
- Name (optional)
- Birth date/time fields (
year,month,day,hour,minute) - Location fields (
city,lat,lng,tz_str) house_system: "placidus"zodiac_type: "tropical"interpretation: { enable: true, style: "improved" }include_features: ["asc", "mc", "chiron", "lilith", "true_node", "mean_node"]include_speed: trueinclude_dominants: true
The chart request uses a tuned visual config with:
- light theme
- explicit ring and line widths
- per-aspect line colors (conjunction/opposition/trine/square/sextile/quincunx)
- enabled display points: planets + ASC + node + Lilith + Chiron
The response SVG is injected client-side and supports interaction behaviors implemented in the report view.
The /report page renders:
- Natal wheel (SVG)
- 1st House / ASC section
- 10th House Cusp / MC section
- Planet interpretation blocks
- All Aspect Dynamics table
- Thematic interpretation sections
- Right-column reference rail (birth data, planet positions, objects, angles, houses, elements)
app/page.tsx— input flowapp/report/page.tsx— report routeapp/api/geo/search/route.ts— geo proxyapp/api/natal/calculate/route.ts— natal proxyapp/api/natal/chart-svg/route.ts— SVG proxycomponents/form/*— input form modulescomponents/report/*— report rendering and chart interactionslib/api/freeastro.ts— upstream API service layerlib/schemas/astro.ts— Zod schemaslib/types/astro.ts— strict TypeScript contractslib/formatters.ts— display utilitieslib/errors.ts— API error mapping
Before deploying:
npm run lint
npm run test -- --run
npm run buildExpected outcome:
- lint clean
- tests passing
- successful production build
- Import repository in Vercel
- Add env var
FREE_ASTRO_API_KEY - Deploy
- Verify:
/form submits- city autocomplete returns results
/reportrenders interpretation and chart- API routes respond with expected status/error mapping
- API key is server-only (
.env.local/ Vercel env) - No direct client calls to upstream FreeAstroAPI
- All external calls are proxied via Next route handlers
PRs are welcome.
- Create a branch
- Make focused changes
- Run lint/test/build locally
- Open a PR with clear reproduction and expected behavior
Astrology data powered by FreeAstroAPI.
Built with Next.js, TypeScript, Tailwind CSS, React Hook Form, and Zod.

