Most "free HTML template" downloads end the same way: you unzip it, and there's a package.json, a gulpfile, a node_modules you have to install, and a build step you have to run before you can even see the thing. For a page that is 90% text and images.
Here is the same landing page, built the other way: one file, zero dependencies.
The whole thing is this
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Your product</title>
<style>
/* everything lives here */
</style>
</head>
<body>
<!-- your sections -->
<script>
// and here
</script>
</body>
</html>
That's it. No CDN links, no font imports, no bundler. Open it in a browser and it runs — even with the wifi off.
The five rules that keep it clean
I've built 56 templates under this constraint. These are the rules that mattered:
1. Zero external requests. No Google Fonts, no Font Awesome, no jQuery from a CDN. Use font stacks:
body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; }
You lose the custom typeface. You gain a page that renders instantly and never breaks because someone else's CDN is down.
2. Decorate with CSS, not images. Gradients, box-shadow and solid colors replace 90% of background images:
.hero {
background: linear-gradient(135deg, #0d1117 0%, #161b22 60%, #1a2332 100%);
box-shadow: inset 0 -1px 0 rgba(255,255,255,.06);
}
No image requests, no layout shift, and the client can recolor the whole page by changing two hex values.
3. Icons as inline SVG primitives. Not <path> — primitives:
<svg viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor" stroke-width="2">
<circle cx="12" cy="12" r="9"></circle>
<line x1="12" y1="8" x2="12" y2="13"></line>
<circle cx="12" cy="16" r="1" fill="currentColor"></circle>
</svg>
circle, rect, line, polyline, polygon. They weigh almost nothing, they inherit currentColor, and unlike a copy-pasted <path> you can actually read what they do.
4. A mobile menu in six lines. No framework needed:
document.querySelector('.burger').addEventListener('click', function () {
document.querySelector('.nav-links').classList.toggle('open');
});
@media (max-width: 768px) {
.nav-links { display: none; }
.nav-links.open { display: flex; flex-direction: column; }
.burger { display: block; }
}
5. Keep it under ~650 lines. If a landing page doesn't fit in 650 lines, it's not a landing page anymore — it's an app, and you should reach for a real framework.
When this is the wrong tool
I'll be honest about the trade-off, because it's real:
- App with routing, auth and state? Use a framework. Don't do this.
- Site with 200 pages and a CMS? Use a static site generator.
- Team of 6 editing the same page? You want components, not one big file.
But for a landing page, a portfolio, a restaurant menu, a clinic site, a coming-soon page — the toolchain is pure overhead. It costs you build errors, dependency upgrades, and a client who can't change a phone number without calling you.
Take one and try it
Here's a complete coming-soon page built this way — live countdown, email capture, responsive, one file. Free, no signup, no email wall:
If you want to see the approach at scale, there are 56 of them (SaaS, agency, restaurant, clinic, gym, real estate, crypto, esports and more) at segcom.net — every demo is the actual file running in your browser, not a screenshot.
What would you add to the rules list?
Top comments (0)