From code to a live URL
How localhost becomes a real website — git/GitHub, a host, a domain, DNS, HTTPS, production env vars, and preview deploys. (Module 6 is the interview-depth version.)
Your app works on localhost. How does it become a real website someone can visit?
This chapter is the shipping vocabulary — git, a host, a domain, DNS, HTTPS — so you
can take any project from your laptop to a live URL and read the logs when it breaks.
(Branching, CI/CD, and security get interview depth in Module 6; this gets you
one app live.)
From laptop to live URL
A deploy is a pipeline: you push code, the host builds it, and it goes live. Push a
branch instead of main and most hosts give you a preview URL for free. The crucial
mental shift from localhost: you no longer run the build — the host does, in a
clean environment, every time you push. “Works on my machine” stops mattering; what
matters is whether it builds on the host.
Which host? Static/frontend vs app/server
Hosts split roughly into two camps: those great at serving static/frontend output, and those that run an always-on server/backend. Most modern platforms do both, but knowing the split tells you what to ask for — and which one a given app actually needs.
| Static / frontend host | App / server host | |
|---|---|---|
| Serves | pre-built files + edge functions | a long-running process you control |
| Examples | Vercel, Netlify, Cloudflare Pages | Railway, Render, Fly |
| Great for | Astro/Next/React sites, fast previews | a Node/Python server, a DB, websockets |
| Scaling | automatic, scales to zero | you size + manage the instance |
| Reach for it when | the output is mostly pages/assets | you need state that stays running |
How a name becomes your site
When someone types your domain, DNS resolves it to your host, and HTTPS secures the
connection — all before your first byte of HTML arrives. You connect a domain by
adding a DNS record that points at your host: an A record points at an IP address,
a CNAME points at another name (the host’s). HTTPS then adds two things: the
connection is encrypted (no one between can read it) and the server’s identity is
verified (you’re really talking to myapp.com, not an impostor).
Env vars per environment, and CI/CD
Your code reads process.env.DATABASE_URL; you set the value in the host’s
environment-variables panel — and you set it separately for preview and
production, so a preview deploy hits a test database, not the real one. This is
also where the deploy becomes CI/CD: on every push the host runs the same pipeline
automatically — push → build → test → deploy — so shipping is a git push, not a
manual ritual.
01 Learning objectives
0 / 6 done02 Curated reading
03 Knowledge check
- 01easy
DNS is responsible for…
- 02easy
Where do production environment variables (e.g. DATABASE_URL) get their values?
- 03easy
When a deploy fails, the host's build and runtime logs usually say why.
- 04medium
A preview deploy is…
04 Interview questions
browse all ↗What gets asked on this topic — tap a card for how to approach it, the follow-ups, and the trap. Company tags are best-effort & sourced.
-
What is version control, and what is a GitHub repo — in one line each?
Version control (Git) tracks the history of your code over time, lets you branch and merge, and lets you go back to any past state. A GitHub repo is a hosted home for a Git repository — the shared remote copy that you push to, others pull from, and deploys are triggered from.
Git is the tool; GitHub is a hosting service for Git repos (with PRs, issues, and CI on top).
Follow-ups they push on- What's the difference between a commit and a push?
- What is a branch for?
Red flag Conflating Git and GitHub. Git is the version-control tool; GitHub is one place to host Git repos.
source: GitHub — Hello World ↗ -
Modern hosts — Vercel, Netlify, Cloudflare, Railway, Render, Fly. What's the rough split between them?
Roughly two camps. Static / frontend hosts (Vercel, Netlify, Cloudflare Pages) are tuned for serving built frontends and serverless functions at the edge — push a repo, they build and serve it. App / server hosts (Railway, Render, Fly) are tuned for long-running servers, databases, and containers.
The line blurs (most do some of both), but the orientation-level instinct is: a static site or a frontend-plus-functions app leans toward the first group; a long-running backend with its own database leans toward the second.
Follow-ups they push on- Where would you host a static marketing site vs a websocket server?
- What does 'edge' mean here?
Red flag Treating all hosts as interchangeable — a pure static host won't run your always-on stateful backend well.
source: Vercel — Deployments overview ↗ -
Walk the path from a domain name to your running app. What does HTTPS/SSL add?
Domain → DNS → host. You point the domain at the host using DNS records: an A record maps a name to an IP address; a CNAME maps a name to another name (e.g. your-app.vercel.app). The browser resolves the name via DNS, then connects to the host.
HTTPS/SSL adds encryption and identity: it encrypts traffic so it can't be read or tampered with in transit, and the certificate proves the server is who it claims to be. Without it, credentials and data travel in plaintext.
Follow-ups they push on- When do you use an A record vs a CNAME?
- Why does the padlock matter beyond 'it's secure'?
Red flag Thinking DNS 'hosts' the site — DNS only maps the name to an address; the host serves the actual app.
source: Cloudflare — What is DNS? ↗ -
What is a preview deploy, and where do you look first when a deploy breaks?
A preview deploy is a full, live build of a branch or pull request at its own URL, separate from production — so you (and reviewers) can click through the change before it ships. Production and preview typically have separate env vars, which is a common gotcha when something works in preview but breaks in prod.
When a deploy breaks, read the build logs first (did it compile?), then the runtime logs (is it crashing at request time?), and check that the right env vars exist for that environment.
Follow-ups they push on- Why might something work in preview but fail in production?
- What's the difference between a build-time and a runtime error?
Red flag Forgetting prod and preview have different env vars — a missing prod secret is a classic 'works on preview' failure.
source: Vercel — Deployments overview ↗ -
What does CI/CD mean at a high level?
CI (Continuous Integration) is automatically building and testing your code every time you push, so problems surface early. CD (Continuous Delivery/Deployment) is automatically taking the code that passed and deploying it.
The whole pipeline, orientation-level: push → build → test → deploy. The point is no manual steps and no 'works on my machine' — every change goes through the same gated, repeatable path.
Follow-ups they push on- What's the difference between continuous delivery and continuous deployment?
- Why run tests before deploying?
Red flag Thinking CI/CD is one tool — it's a practice/pipeline; many tools implement it.
source: GitHub — Hello World ↗ -
Walk the full chain from a git commit to a live URL. What happens at each step?
Repo → build → bundle → deploy → host. You push a commit to the repo (e.g. GitHub). That triggers a build on the host: it installs dependencies and runs your build command, which bundles your source — many files of TS/JSX/CSS — into a small set of optimized, browser-ready static assets (
dist/). The host then deploys those artifacts (copies them to its servers/CDN) and serves them at a URL.The mental model that matters: your source code is *not* what runs — the built bundle is. A push kicks off a pipeline that transforms source into deployable artifacts and puts them somewhere always-on. Modern hosts collapse all of this into 'git push and we handle the rest'.
What a strong answer coversChain: push to repo → host builds → bundler produces optimized
dist/→ deploy → live URL.Bundling turns many dev files into a few optimized, browser-ready assets.
What runs in prod is the build output, not your raw source.
Modern hosts trigger the whole pipeline automatically on push.
Quick self-checkAfter `git push`, your host shows a live site. What did the browser actually download?
-
Wrong — browsers don't run TS/JSX; it must be transpiled and bundled first.
-
Correct — the build step turns source into browser-ready assets, and those are what get served.
-
Wrong — the repo is source storage; it isn't shipped to visitors.
-
Wrong — that's not how web apps work; the browser downloads HTML/CSS/JS assets.
Follow-ups they push on- What does a bundler (Vite, esbuild) actually do to your files?
- Why isn't your raw `.tsx` source what the browser downloads?
Red flag Thinking the browser runs your source files — it runs the bundled, transpiled output; a build step sits between your code and what ships.
source: Vite — Building for Production ↗ -
What does a bundler like Vite or esbuild actually do, and why do you need one?
A bundler takes your project — dozens or hundreds of source files plus dependencies — and produces a small set of optimized files the browser can load efficiently. Along the way it transpiles modern TS/JSX into plain JavaScript the browser understands, resolves and combines
imports, minifies (strips whitespace and shortens names), tree-shakes unused code, and fingerprints filenames for caching.You need one because browsers don't run TypeScript or JSX, and shipping hundreds of separate files would be slow. The bundler is the bridge between 'how you write code' (modular, modern, typed) and 'what loads fast in a browser' (few, small, plain-JS files).
What a strong answer coversTranspiles modern TS/JSX → plain browser-compatible JavaScript.
Combines many modules and resolves
imports into a few output files.Minifies and tree-shakes to cut size; fingerprints filenames for caching.
Bridges 'nice to write' (modular/typed) and 'fast to load' (few small files).
Follow-ups they push on- What is tree-shaking?
- Why does the browser need TS transpiled before it can run it?
Red flag Confusing the bundler (prepares code to ship) with the host (serves it) — they're different stages; the bundler runs during the build.
source: Vite — Why Vite (the problems it solves) ↗ -
What's the difference between a build-time error and a runtime error when a deploy goes wrong?
A build-time error happens while the host is compiling/bundling your code — a type error, a syntax error, a missing import. The build fails, nothing gets deployed, and you read the build logs to find it. Production keeps serving the last good deploy.
A runtime error happens after a successful deploy, when the live code actually executes a request — a null reference, a crashed API call, a missing env var the code reads at request time. The build passed, the site is 'up', but pages error; you read the runtime/function logs to find it. First diagnostic question on any broken deploy: did it fail to build, or did it build and then fail to run?
What a strong answer coversBuild-time: fails during compile/bundle (type/syntax/import errors) → check build logs; nothing deploys.
Runtime: fails while serving requests on a deployed build → check runtime/function logs.
A failed build leaves the previous good version live; a runtime error means broken-but-deployed.
First question: did it fail to build, or build fine then fail to run?
Quick self-checkYour deploy succeeds and the site loads, but one page throws 'cannot read property of undefined' for some users. What kind of error is this?
-
Wrong — the build succeeded; this surfaces only while running.
-
Correct — it appears during request execution on a deployed build, so it's a runtime issue.
-
Wrong — the site loaded, so DNS resolved fine.
-
Wrong — a bundler failure would have failed the build, not produced a live-but-broken page.
Follow-ups they push on- A missing env var — is that more likely build-time or runtime?
- Why might TypeScript catch a build-time error that JS would only hit at runtime?
Red flag Looking in the build logs for a problem that's actually a runtime crash (or vice versa) — knowing which phase failed points you at the right log.
source: Vercel — Logs (build vs runtime) ↗ -
How do you wire the same secret (like an API key) into local dev, preview, and production without committing it?
Locally, you keep secrets in a
.envfile that is git-ignored (and you commit a.env.examplewith the keys but not the values, so teammates know what's needed). The code reads them via the environment (process.env.API_KEY), never hardcoded.For preview and production, you set the same variable names in the host's environment-variable settings (the dashboard or CLI), with environment-specific values. Each environment can hold a different value — a test key for preview, the real key for prod. The code stays identical; only the supplied values differ. The secret never enters git in any environment.
What a strong answer coversLocal: git-ignored
.env; commit.env.example(names only, no values).Code reads from the environment (
process.env.X), never hardcodes the value.Preview/prod: set the same names in the host's env-var settings, per-environment values.
Same code everywhere; only the injected values differ; nothing secret hits git.
Follow-ups they push on- Why commit a `.env.example` but never the real `.env`?
- Why might preview use a different API key than production?
Red flag Setting env vars only locally and forgetting the host — the build/runtime in prod has no value, so it works locally and breaks when deployed.
source: Vite — Env Variables and Modes ↗ -
What does a CDN do, and why is serving your app from 'the edge' faster?
A CDN (Content Delivery Network) is a global network of servers that cache your static assets close to users. Instead of every visitor fetching files from one origin server (which might be a continent away), they're served from a nearby edge location, cutting the round-trip distance and latency.
'The edge' just means 'physically close to the user'. For a static frontend, the whole site can be cached at the edge so it loads fast worldwide. The tradeoff to remember: cached content is fast but can be stale until it's invalidated, and truly dynamic/personalized responses can't simply be cached for everyone.
What a strong answer coversA CDN caches assets on servers worldwide, serving each user from a nearby location.
'Edge' = close to the user; less distance means lower latency.
Great for static assets and frontends; the whole site can live at the edge.
Tradeoff: cached content can be stale; per-user dynamic responses don't cache trivially.
Follow-ups they push on- What kind of content is easy to cache at the edge vs hard?
- What does 'cache invalidation' mean and why is it tricky?
Red flag Assuming everything benefits from edge caching — highly dynamic or per-user responses can't be shared from a cache, and stale caches serve old content until invalidated.
source: Cloudflare — What is a CDN? ↗