惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

GbyAI
GbyAI
T
Tenable Blog
Webroot Blog
Webroot Blog
L
Lohrmann on Cybersecurity
S
Securelist
S
Schneier on Security
NISL@THU
NISL@THU
Know Your Adversary
Know Your Adversary
C
Cybersecurity and Infrastructure Security Agency CISA
T
The Exploit Database - CXSecurity.com
L
LINUX DO - 热门话题
C
CXSECURITY Database RSS Feed - CXSecurity.com
O
OpenAI News
I
Intezer
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
TaoSecurity Blog
TaoSecurity Blog
S
Secure Thoughts
Application and Cybersecurity Blog
Application and Cybersecurity Blog
P
Privacy International News Feed
H
Hacker News: Front Page
N
Netflix TechBlog - Medium
M
MIT News - Artificial intelligence
博客园 - Franky
PCI Perspectives
PCI Perspectives
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Microsoft Azure Blog
Microsoft Azure Blog
MongoDB | Blog
MongoDB | Blog
L
LangChain Blog
P
Proofpoint News Feed
S
Security Affairs
WordPress大学
WordPress大学
The Last Watchdog
The Last Watchdog
S
SegmentFault 最新的问题
小众软件
小众软件
F
Full Disclosure
博客园 - 叶小钗
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
T
The Blog of Author Tim Ferriss
Simon Willison's Weblog
Simon Willison's Weblog
P
Palo Alto Networks Blog
Security Latest
Security Latest
P
Proofpoint News Feed
月光博客
月光博客
T
Tailwind CSS Blog
Scott Helme
Scott Helme
Hacker News - Newest:
Hacker News - Newest: "LLM"
Google Online Security Blog
Google Online Security Blog
T
Threat Research - Cisco Blogs
Help Net Security
Help Net Security
Project Zero
Project Zero

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python) The Hidden Cost of AI Systems Nobody Talks About. undefined vs undeclared, and how typeof behaves Switching from file-based jobs to NATS/Kafka in Rust without changing code io_uring Adventures: Rust Servers That Love Syscalls Why Agentic AI is Killing the Traditional Database The POUR principles of web accessibility for developers and designers Quantum Neural Network 3D — A Deep Dive into Interactive WebGL Visualization How To Install Caveman In Codex On macOS And Windows Automation Pipeline Reliability: Why Your Workflow Breaks When Nobody Is Watching I Built an 'Open World' AI Coding Agent — It Works From ANY Folder From Freelancing to Product: A Tech Service Company's SaaS Transformation China's AI Giants: Adding Tencent Hunyuan & ByteDance Doubao to AI University (74 Providers) On the Vibe Coders and Their Lies clerk: Auto-Summarize Your Claude Code Sessions AI Weekly — 2026/04/10–04/17 | The Model Lockdown Is Here, but the Toolchain Is the Real Battleground AI 週報 — 2026/04/10–2026/04/17 模型封鎖潮來了,但工具鏈才是真戰場 Maybe this is how Open-Source apps are born... 🚀 Fine-Tune LLMs with LoRA and QLoRA: 2026 Guide tRPC v11 + Next.js App Router: End-to-End Type Safety Without the Boilerplate ShadCN UI in 2026: Why I Stopped Installing Component Libraries and Started Owning My Components SaaS Billing in React Server Components: Stripe + Supabase Without a Single `useEffect` Join our DEV Weekend Challenge — $1,000 in Prizes Across TEN winners! Submissions Due April 20 at 6:59 AM UTC. Implementing FSRS Spaced Repetition in Flutter + Supabase — Adding Memory Science to an AI Learning App "I Texted My Localhost From the Train — Claude Code Fixed the Bug Before I Got Home" I Built a Sales Prep AI and It Went Deeper Than Expected Design to Code #2: One JSON, Eleven Outputs Solving the 100M-Row Problem: A Summary Table Pattern for High-Volume Push Notification Logs Flutter Web With Wasm: What Actually Changes For Developers I Built 50 Royalty-Free Soundtracks for My Side Project in a Weekend Using AI Music Generation The Vibe Coding Security Checklist: 7 Things to Check Before You Ship Stop Letting Googlebot Guess Fix Your React App's SEO Right Desconstruindo o Streaming do LinkedIn: Como Criar um Engine de Extração de Vídeo de Alta Performance com HLS e FFmpeg (EDA Part-1) EDA (Exploratory Data Analysis) Explained With Real Life — Why Looking at Your Data Is the Most Important Step in Machine Learning Brand Relationship Management at Scale: Our 4-Touch Outreach System for 200+ Brands Why String.fromEnvironment() Might Return an Empty String in Dart JGuardrails 1.0.0 — Hardening Java LLM Apps Against Jailbreaks, Toxicity, and Prompt Injection Plan and Schedule a Full Week of Threads Content From One Claude Conversation Coding Cat Oran Ep3, Five Tables Changed Everything Updated: BFF Pattern I'm done watching freelancers get buried by 200 proposals. So I'm building the alternative. This is my first post BFS Algorithm in Java Step by Step Tutorial with Examples Tracking LLM Pricing Monthly: An Open Dataset for 22 AI Models How We Measure Content ROI on a Comparison Site: Revenue Attribution Without Perfect Data Introducing Nova AI Ops: The AI-Native Operating System for SRE Teams I built a free desktop video downloader for Windows — Grabbit How Talkie OCR Helps Vision-Impaired & Dyslexic Users Read the World Around Them VRCFaceTracking安装和iPhone面捕配置教程,有bug Even CrowdStrike Can't See Your Agents The Automation Gold Rush: What n8n Workflows and Claude Are Opening Up for Developers Right Now
The Forgotten Joy of `node app.js`
Viktor Lázár · 2026-04-29 · via DEV Community

There used to be a moment, ten years or so ago, when you could go from "I have an idea" to "I have a running web server" in about thirty seconds:

// app.js
const express = require('express')
const app = express()

app.get('/', (req, res) => res.send('hello'))

app.listen(3000)

Enter fullscreen mode Exit fullscreen mode

node app.js

Enter fullscreen mode Exit fullscreen mode

That was the whole thing. One file. One command. You could paste it into a Slack message. You could drop it in a Gist and someone could run it. A tiny webhook receiver, a debug dashboard, an internal tool, a stub API — the entire project lived in a single buffer in your editor.

Then frontend frameworks happened, and somewhere along the way we collectively decided that "starting a new project" meant something else entirely.

The scaffold tax

Today, the canonical first step in starting a new app is no longer writing code. It is running a command that writes code for you:

npx create-next-app@latest my-app
npx create-react-app my-app
npm create vite@latest
npx create-remix

Enter fullscreen mode Exit fullscreen mode

What comes back is not a file. It is a tree. Configuration files for tooling you have not yet decided to use. A pages/ or app/ directory with conventions you must learn before you can write a single line. A tsconfig.json you did not write. ESLint rules. Prettier rules. A .gitignore. A README.md describing the scaffold itself. A package.json with twelve dependencies and four scripts you did not pick.

And, critically, there is no path back to a single file. The scaffold is the unit of starting. There is no framework dev ./App.jsx. There is only framework new my-project, which produces forty files, of which you will edit two.

This is fine when you are starting a real product. It is absurd when you are not.

What we lost

The single-file app is not a relic of a less mature ecosystem. It is a fundamentally different mode of working — one the modern frontend toolchain has quietly priced out of existence.

Specifically, we lost:

The throwaway. The five-minute hack to verify that an idea works. The "let me just see what this looks like rendered" experiment. With a scaffold, the cost of starting is high enough that you don't bother. You either pollute an existing big project, or you open the browser DevTools console.

The teaching artifact. A blog post used to be able to say here, run this file. Now it says clone this repo. The reader is no longer reading code; they are operating a project.

The micro-app. The three-route admin tool. The internal status page. The webhook that posts a Slack message. Things that should be one file are now twenty, because the framework demands it.

The shareable Gist. I cannot send you a single .jsx file and have you run it. I have to send you a repository — or a CodeSandbox URL, which is its own confession that the local toolchain has gotten too heavy.

The curl-and-run. Plain Node lets you stream a program straight from a URL into the runtime, no file on disk: curl https://gist.githubusercontent.com/.../app.js | node. No clone, no install, no project to set up. The source travels over the wire, lands in the interpreter, runs. The same pattern should work for a single-file frontend app — curl https://.../App.jsx | npx some-framework dev - — and the fact that this is unimaginable today is the most concrete possible measurement of how heavy "starting a frontend app" has become. We have a JavaScript-shaped hole in our shells that the language used to fit through.

There is a fractal version of this same pain one level down. Even inside a project, modern React's "use client" directive forces single features to be sharded across multiple files for purely mechanical reasons — the same disease, at smaller scale. I wrote about that version separately in The "use client" Tax. What follows here is the project-level shape of the same problem: even when the whole app should be one file, you are not allowed to write it that way.

The shape of the fix

Imagine, for a second, that this just worked:

npx next dev ./App.jsx

Enter fullscreen mode Exit fullscreen mode

One file. One command. The framework picks it up, runs it, hot-reloads it, serves it. No next.config.js, no pages/, no app/, no package.json. If you decide later that you want a real project, you make the directory, add the config, split the file. The framework grows with you instead of demanding everything upfront.

The technology to do this is not hard. Frameworks already build on dev servers — Vite, esbuild, Turbopack — that can resolve and bundle a single entry point. The framework conventions (file-based routing, layouts, server components) are conventions over the bundler, not replacements for it. There is no fundamental reason a framework's CLI cannot accept a path to a .jsx file and Just Work, with the conventions kicking in only once you opt into a directory layout.

The reason it doesn't work is not technical. It's cultural. We have decided, somewhere along the way, that the project is the unit of frontend code, and the file is merely an implementation detail. Backend frameworks never made that mistake. You can still write a fifteen-line server.js and run it. You can still write a Flask app in one file. You can still put a Go HTTP handler in main.go and ship it. Scaffolds are offered as a convenience, not enforced as a precondition.

Frontend should be no different.

One file in, one file out

The single-file dev story is only half of the picture. The other half is what comes out when you build.

Today, building a frontend project produces another tree. A .next/ directory. A dist/ directory. A .output/ directory. Hundreds of chunked JavaScript files, manifests, server bundles, client bundles, route maps — and a node_modules you must ship alongside it, or carefully fold into the deployment artifact. Running the result usually means another framework-specific command (next start, node .output/server/index.mjs) that depends on the surrounding directory structure being intact.

It should be possible to do this:

some-framework build ./App.jsx -o app.js
node app.js

Enter fullscreen mode Exit fullscreen mode

One file in. One file out. No node_modules, no config, no manifest, no dist/ to preserve. A single .js that boots an HTTP server, serves the assets it needs (inlined or referenced), and runs on any Node install with nothing else next to it.

Backend developers have had this for years, just under different names. Go produces a static binary. Deno compiles to a single executable. esbuild can bundle a Node program into one file. The pattern is universal: take everything the program needs, fold it into one artifact, ship that. Nothing about a React app — even a server-rendered, server-component-heavy React app — fundamentally prevents the same thing.

What this unlocks is bigger than convenience:

  • Trivial deployment. scp app.js server:/srv/ && node app.js. No CI artifact pipelines, no Docker images for a webhook receiver, no Kubernetes for a status page.
  • Reproducibility. The artifact is a file. You can hash it, version it, archive it, email it. Not a directory whose contents quietly differ depending on which npm install produced it.
  • Sandboxes. A single file is something a sandbox runtime — a serverless platform, a worker, a container — can swallow whole, with no need to mount a node_modules.
  • Distribution. Internal tools become as easy to share as a CLI binary. "Drop this on the server and run it" is a workflow we lost the moment frontends grew a build directory.

The deploy story for a small app should be as small as the app. Right now, even a thirty-line frontend deploys like a monorepo.

And then AI showed up

The scaffold tax used to be paid mostly by humans — a one-time annoyance you absorbed at project start, then forgot about. AI coding tools have quietly turned it into a recurring tax, paid on every interaction.

When you ask an AI to modify a single-file app, it can read the entire program in one shot, hold the whole behavior in its working memory, and reason about a change with confidence. The file is the project. There is nothing else to discover.

When you ask an AI to modify a scaffolded project, it has to do archaeology first. Where does routing live? Which tsconfig paths are aliased? Is that import resolved by a framework convention or by the bundler? Is app/ the routing root, or a coincidentally-named folder? What does the project's ESLint config forbid? Half the request gets spent loading context that wasn't actually relevant to the change.

This shows up as:

  • Worse answers, because the model is reasoning under a noisier prompt.
  • Slower answers, because more files have to be read before it can act.
  • More expensive answers, because tokens are not free, and a fresh agent re-discovers the same project structure on every session.
  • More fragile answers, because the model has more surface area on which to misread a convention.

A one-file app is, by accident, the ideal substrate for AI-assisted coding: the entire program fits in a single attention window, every symbol resolves locally, and the change you ask for can be made without crawling a directory tree first. The convention overhead we built up to make starting a project "easier" turns out to be overhead we now pay every time we ask a tool to help us edit one.

The same things that made the single-file app pleasant to write by hand — small surface, no hidden conventions, nothing to discover — make it the format AI tools handle best. We just stopped producing apps in that shape.

Why this matters

There is a subtle compounding effect to all of this. When the cost of starting is high, people start fewer things. When people start fewer things, the ecosystem gets less weird, less experimental, less playful. The thirty-line idea that would have become a beloved internal tool never gets written, because the scaffolding tax was higher than the energy budget for the experiment.

The modern frontend stack is extraordinarily capable. It can render server components, stream HTML, hydrate selectively, generate static pages, run on the edge, do incremental builds. None of that is at odds with also being able to do this:

some-framework dev ./App.jsx

Enter fullscreen mode Exit fullscreen mode

It's a small surface area. It's enormously valuable. And it is, conspicuously, missing from almost every option you'd reach for today.

The good news is that almost. If you look around carefully, this capability is starting to reappear in the corners of the ecosystem — runtimes that treat the single file as a first-class entry point, not as a degenerate case of a project. It's worth keeping an eye on.

The thirty-second app deserves to come back.