cosmic-explorer-svelte Svelte Themes

Cosmic Explorer Svelte

Basic Svelte App

Cosmos Observer โ€” Svelte

A deep-space observatory interface for browsing NASA's universe data. Navigate between two views โ€” the Astronomy Picture of the Day and a live Asteroid Watch โ€” using a persistent bottom navigation bar.

Built with Svelte 5 (runes) and SvelteKit, Vite, and plain CSS custom properties.

๐Ÿ”ญ Live site: https://myapp-zeta-weld.vercel.app


Features

โ—ˆ Picture of the Day

Loads today's NASA Astronomy Picture of the Day automatically on open. Pick any date from 16 June 1995 onwards and click Receive Signal to load that day's image or video alongside its title, description, date, and copyright.

โ—Ž Asteroid Watch

Loads Near Earth Objects approaching Earth today automatically on open. Asteroids are sorted by proximity to Earth. Click any card to expand it and see:

  • Velocity (km/h)
  • Estimated diameter range (metres)
  • Closest approach date and time
  • Orbiting body
  • Link to the JPL Small Body Database entry

Potentially hazardous asteroids are flagged in red with a pulsing dot. The date picker accepts dates up to 2100-12-31 for predicted future approaches. A banner appears when a future date is selected.


Tech stack

Framework Svelte 5 โ€” runes ($state, $derived, $props, $bindable)
App framework SvelteKit
Build tool Vite
Styling CSS custom properties โ€” all tokens in src/lib/styles/tokens.css
Fonts Space Mono ยท Cormorant Garamond via Google Fonts
APIs NASA APOD API ยท NASA NeoWs API
Component tests Vitest + Svelte Testing Library
E2E tests Playwright (Chromium + Firefox)
Component explorer Storybook 8
CI GitHub Actions
Deployment Vercel

Getting started

1. Clone and install

git clone https://github.com/your-username/cosmos-observer-svelte.git
cd cosmos-observer-svelte
npm install

2. Add your NASA API key

Create a .env file in the project root:

VITE_NASA_API_KEY=your_key_here

Get a free key at api.nasa.gov. Without one the app falls back to DEMO_KEY, which is rate-limited to 30 requests/hour per IP.

โš ๏ธ Never commit your .env file โ€” it is listed in .gitignore.

3. Start the dev server

npm run dev

Opens at http://localhost:5173


Scripts

Script What it does
npm run dev Start Vite dev server
npm run build Production build
npm run preview Serve the production build locally
npm run lint ESLint โ€” reports issues, no autofix
npm run format:check Prettier โ€” checks formatting, no autofix
npm run format Prettier โ€” fixes formatting in place
npm run test Vitest โ€” single run, exits when done
npm run test:watch Vitest โ€” watch mode for development
npm run e2e test Playwright โ€” headless, Chromium + Firefox
npm run e2e test -- --ui Playwright โ€” interactive UI mode
npm run e2e test -- --headed Playwright โ€” visible browser window
npm run storybook Storybook dev server on port 6006
npm run build-storybook Build static Storybook into storybook-static/

Project structure

myapp/
โ”œโ”€โ”€ src/
โ”‚   โ”œโ”€โ”€ app.html                       # HTML shell
โ”‚   โ”œโ”€โ”€ routes/
โ”‚   โ”‚   โ”œโ”€โ”€ +layout.svelte             # Root layout โ€” imports tokens.css
โ”‚   โ”‚   โ””โ”€โ”€ +page.svelte               # Entry page โ€” renders App shell
โ”‚   โ”œโ”€โ”€ lib/
โ”‚   โ”‚   โ”œโ”€โ”€ api/
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ Apod.js                # APOD API wrapper
โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ Neo.js                 # NeoWs API wrapper
โ”‚   โ”‚   โ”œโ”€โ”€ components/
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ Apod/
โ”‚   โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ ApodHeader.svelte  # Heading + ApodVisual
โ”‚   โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ ApodVisual.svelte  # CSS orbiting particle animation
โ”‚   โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ ApodDatePicker.svelte # Date input + Receive Signal button
โ”‚   โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ ApodImage.svelte   # Renders <img> or <iframe>
โ”‚   โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ ApodCard.svelte    # Full result card
โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ Neo/
โ”‚   โ”‚   โ”‚       โ”œโ”€โ”€ NeoHeader.svelte   # Heading + NeoOrbitVisual
โ”‚   โ”‚   โ”‚       โ”œโ”€โ”€ NeoOrbitVisual.svelte # Animated orbital rings
โ”‚   โ”‚   โ”‚       โ”œโ”€โ”€ NeoList.svelte     # Count summary + list of NeoCards
โ”‚   โ”‚   โ”‚       โ””โ”€โ”€ NeoCard.svelte     # Expandable asteroid detail card
โ”‚   โ”‚   โ”œโ”€โ”€ styles/
โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ tokens.css             # All CSS custom properties
โ”‚   โ”‚   โ””โ”€โ”€ views/
โ”‚   โ”‚       โ”œโ”€โ”€ ApodView.svelte        # APOD page โ€” auto-loads today on mount
โ”‚   โ”‚       โ””โ”€โ”€ Neoview.svelte         # NEO page โ€” auto-loads today on mount
โ”‚   โ””โ”€โ”€ stories/
โ”‚       โ””โ”€โ”€ Cosmos.stories.js          # Storybook stories
โ”œโ”€โ”€ tests/
โ”‚   โ”œโ”€โ”€ setup.js                       # Vitest global setup
โ”‚   โ”œโ”€โ”€ Apod.test.js                   # Component tests โ€” all APOD components
โ”‚   โ””โ”€โ”€ Neo.test.js                    # Component tests โ€” all NEO components
โ”œโ”€โ”€ e2e/
โ”‚   โ””โ”€โ”€ Cosmos.spec.js                 # Playwright e2e tests
โ”œโ”€โ”€ .github/workflows/
โ”‚   โ””โ”€โ”€ ci.yml                         # CI: lint + format + test + e2e
โ”œโ”€โ”€ playwright.config.js
โ”œโ”€โ”€ vitest.config.js
โ”œโ”€โ”€ vite.config.js
โ””โ”€โ”€ svelte.config.js

Svelte 5 runes

This project uses Svelte 5's rune-based reactivity rather than the legacy Svelte 4 API. Key patterns used throughout:

// Reactive state
let loading = $state(false);

// Derived value
let hazardousCount = $derived(neos.filter((n) => n.is_potentially_hazardous_asteroid).length);

// Props โ€” including bindable for two-way binding
let { value = $bindable(''), loading = false, maxDate, onFetch } = $props();

Event handlers use the HTML attribute syntax (onclick, oninput) rather than Svelte 4's directive syntax (on:click, on:input).


CI / CD

Every pull request to main triggers two parallel GitHub Actions jobs:

Lint, Format and Test โ€” runs ESLint, Prettier check, and Vitest in sequence. All three must pass.

E2E Tests โ€” installs Playwright browsers, starts the Vite dev server automatically via the webServer config in playwright.config.js, then runs the full suite against Chromium and Firefox. The HTML report is uploaded as a workflow artifact on every run.

Merging to main triggers an automatic deployment to Vercel.

Top categories

Loading Svelte Themes