Code

js/main.js and js/config.js — the first modules

Now — the JavaScript. In the code column are both first modules (use the tabs): js/main.js imports from js/config.js and writes text into the page. That's enough to prove the platform works with no tooling.

config.js is one place for all the constants:

// js/config.js — configuration in one place.
export const API_KEY = 'DEMO_KEY';   // get your own free key: https://api.nasa.gov
export const API_URL = 'https://api.nasa.gov/planetary/apod';

export makes a value visible to other files; import pulls it in. These are ES modules — part of the language, working directly in the browser with no bundler. (We start with DEMO_KEY; getting your own key and why you need one is lesson 4.)

Run it through a server. ES modules are fetched by the browser, so the page must be served over http, not opened as a file. The simplest way with no npm is Python (already on most systems):

cd vanilla
python -m http.server 8000
# open http://localhost:8000

(Or the VS Code "Live Server" extension — right-click index.html → "Open with Live Server".)

Verify. In the browser at http://localhost:8000 you should see:

Cosmos is running. It will fetch pictures from https://api.nasa.gov/planetary/apod

If you can read that sentence, you have working HTML, CSS and a JavaScript module that imported another module. With no build tools at all.

Gotcha (modules need a server). Double-click index.html to open it straight from the file explorer — the address becomes file:///…/index.html. The page won't work, and the browser console (F12) shows a CORS error:

Access to script at 'file:///…/js/main.js' from origin 'null'
has been blocked by CORS policy

The reason: a type="module" script is fetched by the browser, and the file:// origin is "null" — the security policy blocks it. This is the first constraint the platform imposes. The fix is simple — serve over http (as above). A "why doesn't this work?" moment worth feeling once, so it never bites you again.