System Architecture

Choosing Application Form — Web / Native / Hybrid

Choosing Application Form — Web / Native / Hybrid

About this article

This article is the first deep dive in the “System Architecture” category of the Architecture Crash Course for the Generative-AI Era series, covering the application form that gets decided first in system architecture.

PC-installed app, browser-based, or smartphone app — the answer to this question binds nearly every downstream design decision: who you hire, how you sell it, what your exit cost looks like. This article covers Native / Web (SaaS/PaaS/IaaS/FaaS) / Hybrid, the inner subdivisions, and case-by-case selection criteria.

“So where does this system run?”

The question always asked in the first week of any new project. It’s not just a technology choice — it determines the shape of the business itself. Selling as a PC app vs offering as a subscription web service vs distributing as a smartphone app: each answer reshapes the engineer skill set, the sales motion, and the customer-support model.

Until the 1990s, “applications” meant boxed software bought at retail and installed. Web apps became viable in the 2000s with broadband and browser maturity. The iPhone in 2007 opened the smartphone-app market. Cloud adoption in the 2010s turned server procurement into pay-as-you-go. The wider the choice, the heavier the cost of getting it wrong.

Form cannot be fixed after the fact. Trying to fix it requires the will to rebuild from scratch. Migrating a Web app to native later — UI rewrite, offline support, store review — costs roughly the same as a new project. Form selection deserves more care than any other technical decision; if you can’t articulate the choice in the first week, postponing the start by a week is cheaper.

The three basic forms

flowchart LR
    USER([User device])
    SERVER([Server])
    NATIVE["Native<br/>(Runs on device)<br/>Windows/iOS/Android"]
    WEB["Web<br/>(Runs on server)<br/>Gmail/Notion/Slack"]
    HYBRID["Hybrid<br/>(On device + Web tech)<br/>Electron/Flutter/RN"]
    USER -.|Fast, hardware control|.- NATIVE
    USER -.|Zero distribution friction|.- WEB
    USER -.|Distribution + cross-platform|.- HYBRID
    NATIVE -. install .-> USER
    HYBRID -. install .-> USER
    WEB --> SERVER
    classDef native fill:#dbeafe,stroke:#2563eb;
    classDef web fill:#fef3c7,stroke:#d97706;
    classDef hybrid fill:#fae8ff,stroke:#a21caf;
    class NATIVE native;
    class WEB web;
    class HYBRID hybrid;
FormRuns whereExamples
Native appClient deviceWindows software, iOS apps
Web appServer-sideGmail, Notion, Slack (web)
Hybrid appClient device (Web tech)Electron, Flutter, React Native

This split is by “where does the code run.” Native runs directly on the user’s device. Web runs on a server and ships results to the browser. Hybrid is the middle ground: “runs on device but built with Web tech.”

The location of execution propagates through distribution method, performance characteristics, update workflow, and platform dependency. “Just pick whatever” is wrong. Projects that start without articulating why this form get warped mid-design. Build the prototype in the final form — the prototype tends to become production.

Native applications

A native application runs directly on top of the device’s OS (Operating System — Windows, macOS, iOS, etc.). Windows .exe, macOS .app, iOS/Android apps. Anything not going through a browser falls here.

Most of computing history was native-led. From 1970s mainframes through 1990s PCs, “using software” meant “installing from physical media.”

Native subtypes:

  • PC software (accounting, image editing, games, etc.)
  • Smartphone apps (LINE, Instagram, camera apps)
  • Embedded systems (ATMs, vending machines, in-car nav)
  • Batch processing (nightly batch, ETL)

Native’s biggest weapons are performance and direct hardware control: GPU (Graphics Processing Unit) for real-time rendering, raw camera-sensor access, fine-grained Bluetooth control, full-speed local storage. These cannot realistically be done through a browser sandbox (the security mechanism limiting Web code’s execution privileges). Video editors, games, 3D modeling, embedded devices, and high-frequency trading still belong to native.

The weakness concentrates around distribution and updates: store-review delays, prompting users to update, OS-specific implementations. Teams that have waited two weeks on App Store review only to be rejected stop picking native casually. Web and hybrid spread because they escaped these chains. But native still has problems only it can solve.

Embedded, gaming, creative — still native’s territory. If 0.1-second latency or direct hardware control is in play, pick native without hesitation.

Web applications

A Web app runs HTML, CSS, and JavaScript in the browser. Gmail, Notion, Google Docs, Slack, Figma. Open the URL and use it — no install, no update prompt. That “zero-friction delivery” has fixed Web as the default candidate for new projects.

Two technical inflection points:

  1. Ajax (Asynchronous JavaScript and XML — async communication without full page reload) around 2005, enabling “update the screen without navigating” and bringing near-native interactivity to the Web.
  2. SPA (Single Page Application — all navigation handled within a single loaded page) maturing in the late 2010s, producing “Web but feels like an app” products like Gmail and Notion.

From the developer’s view, Web’s biggest weapon is structural: distribution friction goes to zero. One deploy and every user is on the latest version. Find a bug, ship the fix in 30 minutes. The lean development cycle this enables is a major reason SaaS exploded over the past 20 years.

Web apps subdivide into four service models:

  • SaaS (Software as a Service) — finished application provided as-is.
  • PaaS (Platform as a Service) — development platform rented out.
  • IaaS (Infrastructure as a Service) — virtual servers rented out.
  • FaaS (Function as a Service) — submit just a function, runs only when called.

Vehicle analogy: SaaS is a dispatch taxi, PaaS is car-share, IaaS is a monthly parking lot, FaaS is on-demand taxi. The only difference is how much you want to maintain yourself. The choice trades scope of management (= responsibility) against degree of freedom.

Web’s strength is the single point of “no install, instant delivery.” All business advantages chain off that.

SaaS

SaaS rents finished applications over the Internet. Gmail, Notion, Slack, Google Workspace, Salesforce. Browser + login = usable in one second. Software is “used,” not “owned”, billed monthly or annually.

The substantive innovation isn’t “runs on the Web” — it’s multi-tenant architecture: one application serving multiple customers (tenants) with logically isolated data, sharing common infrastructure across all customers. When Salesforce introduced this in 1999, traditional packaged-software vendors dismissed it as “unthinkable to put data on shared servers.” Today most business software has fully migrated to SaaS.

ProsCons
Available worldwideLow customizability
No install neededVendor outages affect you
Independent of client performanceVendor lock-in
Always latest featuresRecurring fees, no offline

The technical definition (multi-tenant) and the business definition (any subscription web service) often diverge. When someone says “this is also SaaS,” confirm which sense they mean. Single-tenant (an isolated instance per customer) explodes the operational burden, often degenerating into custom-build territory. Mixing them up will throw your estimate off by an order of magnitude.

For a new B2B/B2C product, defaulting to SaaS-only is the rule. If you can’t write the reason to skip it in 1 minute, don’t skip it.

PaaS

PaaS rents the entire app runtime. OS, middleware (software between OS and app providing shared functionality), runtime (the system that executes programs), scaling (auto-adjusting server count under load) — pre-configured. Developers just write code. git push and the deploy is done; load goes up and instances scale automatically. Heroku (launched 2007) cemented this experience.

PaaS’s substance is removing “OS and middleware fiddling time” from the developer’s job. Server-OS updates, nginx (high-performance web-server software) configuration, automatic SSL renewal, deploy scripts — these tasks unrelated to the app’s core value get delegated to the PaaS vendor.

ProsCons
Higher dev productivityLess freedom than IaaS
Lower cost (no upfront)Vendor lock-in
Easy environment cloningCannot run offline
Auto-scalingHard to handle unique requirements

Examples: Heroku (the original; lost ground for personal use after free-tier removal in 2022), Vercel (Next.js-focused), Fly.io / Render / Railway (newer crowd that filled the post-Heroku free-tier gap), Cloudflare Pages, Salesforce Platform, and the AWS/GCP/Azure managed-service families (App Runner, Cloud Run, App Service, etc.).

In 2026, the first choice for personal use is Fly.io / Render / Railway. For a commercial startup, Vercel (frontend) + Cloud Run / App Runner (backend) is the combo.

Default new apps to PaaS. Going down to IaaS is allowed only when “why PaaS doesn’t work” can be answered in 1 minute. Legitimate reasons: special kernel modules required, GPU instances required, direct integration with existing VPC (Virtual Private Cloud — logically isolated private network in cloud) resources, compliance requiring auditable OS images. Outside those, PaaS is safer. “IaaS just feels cheaper” ignores the fact that operational labor cost makes a $300/month IaaS effectively $3,000/month in real terms.

IaaS

IaaS rents virtual servers over the Internet. AWS EC2, Google Compute Engine, Azure Virtual Machines. The most straightforward form: “rent a server monthly.”

Until AWS EC2’s 2006 launch, “server” meant on-prem (physical machine, power, network — capital expenditure of thousands of dollars and weeks of lead time). EC2 changed that to “minutes and a credit card.” Airbnb, Dropbox, and Slack are all children of the EC2 era — without that shift, most “unicorns” wouldn’t exist.

ProsCons
High freedom (anything possible)Specialty knowledge required
Cheaper than on-premOS / middleware management on you
No hardware to buySecurity is your job
Easy BCP setupCost can exceed PaaS

Since Heroku in 2007, PaaS is even easier” spread, and demand drifted toward higher abstraction. Docker (2013 — packaging app + runtime into a lightweight container) and Kubernetes (2015 — container orchestration) further reduced the necessity of bare IaaS. Today, picking pure IaaS is reserved for compliance constraints or special requirements PaaS can’t meet. “Educational” is a soft choice — what you should learn on work hours is the app’s value, not how to apply OS patches.

FaaS

FaaS runs a single function only when called. AWS Lambda (launched 2014), Google Cloud Functions, Azure Functions, Cloudflare Workers — pure pay-as-you-go, $0 when idle. “Serverless” as a term landed via this model.

FaaS’s substance is the redefinition of infrastructure from “always running” to “runs only when called.” Traditional servers charged whenever they were on, even at zero traffic. FaaS bills only on “execution time × memory × request count,” so a job hit a few times a month costs effectively zero.

Nightly batch, Webhook (HTTP callback fired on external-service events) handlers, admin APIs, image-thumbnail generation — for these intermittent workloads, FaaS dominates.

ProsCons
Implementation without environment concernsLess customization
Pay-as-you-go (cheap)Cold starts (first-call latency)
Auto-scaling, infinite parallelismHard to debug
Quick to shipLimited execution time (minutes)

Running an always-on web server on FaaS is a textbook bad fit. When traffic pauses the container is destroyed, and the next request needs to recreate it — the cold start problem. Node.js: 100-500 ms penalty per cold start. JVM-class: 2-5 seconds. This degrades UX consistently — users don’t distinguish “system is slow” from “my connection is slow.” For always-on APIs, just pick PaaS or container services. Don’t use FaaS for always-on APIs — that’s the classic early landmine.

Hybrid applications

Hybrid apps wrap a Web-tech (HTML/CSS/JS) implementation in a native shell for distribution. Mostly used for mobile, where covering iOS and Android with one codebase is the biggest weapon. For projects without the budget to hire separate teams per OS, hybrid is the de facto standard.

Two lineages:

  1. WebView-style (Cordova, Ionic): embed a browser inside the native app to render Web pages. Easier to implement; behaves like a browser, often heavy.
  2. Native-rendered (React Native, Flutter): code in JS or Dart, mapped to native UI components. Lighter, closer to native UX. The 2026 default.

Traits:

  • OS-independent (the main feature)
  • Easier hiring (Web engineers can do it)
  • Tends to feel heavier than native
  • Can feel browser-like in interactions

Major examples: React Native (Meta), Flutter (Google), Ionic, Electron (desktop). Flutter and React Native are the default for projects that can’t afford separate iOS/Android teams. A mixed model where critical screens stay native and the rest goes hybrid is also common (Instagram and Discord both run React Native + some native).

The known landmine in hybrid: deep native-feature access. Bluetooth fine-control, camera depth sensors, push-notification details — hybrid plugins often lag behind native API updates and break suddenly. Most “app crashes after OS update” stories trace back to plugins. iOS/Android dual-support starts from hybrid; pick native only when you can immediately answer “why hybrid won’t do.”

Web vs Native deciders

AspectWebNative
Distribution / updatesOpen URLApp store
Cross-platformExcellentPoor (re-implement)
PerformanceMid to highHighest
Direct hardware controlLimitedFull
OfflineLimited (PWA)Excellent
Initial startSlowFast (already installed)

If any one of “0.1s latency is fatal,” “direct hardware control,” or “offline mandatory” is non-negotiable, pick native. Otherwise, Web. Games, video editing, CAD, medical-device UIs, and trading terminals fall on the native side. Look at how peers in your industry built it — copying the market’s revealed preference is faster than reasoning from first principles.

PWA (Progressive Web Apps) achieves “near-native” but iOS still imposes restrictions. For full features, go to hybrid or native.

Selection by case

CaseRecommended
Service independent of user/device/locationWeb (SaaS) as default
Business where 0.1s latency is fatalNative (PC software)
Smartphone-first serviceMobile app or Hybrid
Special-purpose terminals (kiosks, vending machines, navigation)Native / embedded
Bulk batch processing of large dataNative (batch)
Building a developer platformMajor clouds dominate; new entry not recommended

For internal business systems, Web is the only reasonable choice. Games and video editing have no realistic non-native alternative — Google Stadia’s 2019-2023 wind-down was the symbol of that wall.

By phase

PhaseMAU rangeRecommendedDecision axis
MVP / validation< 1kWeb (SaaS + Edge/Serverless)Zero distribution friction, daily deploys
Early growth1k-100kWeb (SaaS + CDN + managed DB)Let the cloud scale, focus on code
Scale100k-1MWeb + hybrid mobile as neededDecide on native by CV rate (consider native if browser CV drops below 30%)
Enterprise1M+Web + native + embedded as neededAllow multiple forms for performance / compliance

Picking Electron / React Native / Flutter at the MVP stage is usually overkill. Build a Web app first, gather actual usage data (“70% of users come from mobile,” “70% of repeat use is offline”), and convert to native afterwards. The reverse order burns the validation phase on store reviews. The decision point during scale is conversion rate (CV) through browser dropping below 30%; native investment pays off only after that.

Form-migration traps

Changing form mid-stream is essentially a rebuild. Common traps:

Forbidden moveWhy
”Port Web to native as-is”DOM-assumed UI degrades both performance and UX in native; UI rewrite is mandatory
Decide native -> Web right before releaseiOS/Android behavior differences and offline assumptions can’t reproduce in Web in time
Adopting Electron/RN/Flutter just because “both OSes covered”Plugins can’t keep up on deep native features (Bluetooth, camera depth, push details)
Migrating an always-on API to FaaSCold starts shave UX every time — Edge Runtime or containers are the answer
Distributing hybrid without store reviewiOS Enterprise distribution still has signing/review constraints; check TestFlight/MDM assumptions first

Iron rule of form migration: “run both forms in parallel for 3-6 months.” Killing the old form while building the new one removes the rollback path — a textbook landmine. Issues always surface right after the new launch, and a live old form gives you a fail-back option. Cutting the old over too early turns into a total outage.

The other rule: scope down the migration. “Big-bang” full migration almost always fails outside very small projects. Use the Strangler pattern (gradually replace and eventually retire the old system) — design assuming both old and new run together for a period.

Don’t start a form migration without securing a parallel-running window. Migration without a retreat path is gambling, not design.

The AI-era lens

With AI-driven development (vibe coding — writing code by describing requirements to AI in natural language), the selection axis has shifted from “human learning cost” to “AI’s fluency.” AI’s generation accuracy scales with the quantity and quality of training data. Web has the largest training-data pool and the highest generation accuracy. The drift of new projects to Web will only intensify.

AI-era favorableAI-era unfavorable
Web apps (information density, standard tech)OS-specific native (info dispersed)
React Native / Flutter hybrids (one code, multiple OSes)Separate iOS/Android (duplication cost unchanged with AI)
IaaS + container + IaC (config as code)GUI-required PaaS, custom consoles
FaaS (just write code) / Wasm (WebAssembly — fast portable bytecode)Custom complex runtimes

The common trait of AI-era favorable tech: “complete in code.” AI can read and write code; GUI clicks and proprietary consoles stay outside AI’s reach. IaC rose in relative value for this reason — what was “overkill to write everything in Terraform before AI is now “overkill not to.”

That said, physical limits (latency, hardware, offline) don’t budge with AI. Asking AI “make latency 10ms” doesn’t beat the speed of light. The new axis is the intersection of “AI can write it easily” and “the requirement is met.” GUI dependence and proprietary consoles are heavy AI-era shackles.

AI-era trend — backend-minimized stacks

In the late 2020s, with AI lifting individual developers, “rich frontend, ruthlessly minimal backend” took hold. Combine an idle-zero function-execution environment with a CDN (Content Delivery Network) -served frontend; no always-on server. Personal projects can run production for a few dollars a month or in free tiers. The barrier to entry has dropped to historic lows — comparable to the 1990s “personal site on a home server” era for individual builders.

But “backend-minimized = FaaS only” isn’t accurate. The pattern has split three ways: FaaS (function execution on call), Edge Runtime (lightweight runtime at CDN edge), BaaS (Backend as a Service — auth, DB, functions all in one vendor). All three share idle-zero billing but differ on LLM streaming compatibility and lock-in depth.

PatternExamplesStrengthsWeaknesses
FaaSAWS LambdaRich info, exists on every cloudCold starts, 15-min timeout
Edge RuntimeCloudflare Workers, Vercel EdgeNear-zero cold start, streamingPartial Node compatibility, heavy compute weak
BaaSSupabase, Firebase, ConvexAuth + DB + functions bundledStrong lock-in (Firebase/Convex), pricing cliffs

LLM (Large Language Model) streaming popularity flipped Edge Runtime into the lead. Generative-AI responses arrive as tokens over many seconds, requiring connection-held streaming to the client. Pure FaaS hits cold-start and max-execution-time limits for this; it has retreated toward async batch.

BaaS lock-in differs by product. Firebase and Convex depend deeply on proprietary APIs and data models — escaping is essentially a rewrite. Supabase is open-source-stack (Postgres + PostgREST + GoTrue), self-hostable, and standard SQL — exit cost is comparatively light. “All BaaS is locked in” is too crude; Supabase is “BaaS with an exit.” Estimate “how many days to migrate if the vendor stops” before adopting.

For new projects with LLM streaming, Edge Runtime is the first candidate. FaaS lives in batch and webhook territory.

”Picked IaaS to learn” — a weekend (industry case)

A standard rite of passage: starting a small SaaS as a side project, picking AWS EC2 because “it’ll be educational,” burning the weekend on nginx, systemd (Linux’s daemon manager), domain setup, manually starting PostgreSQL, writing the Let’s Encrypt (free SSL) renewal cron, and finally getting Hello, World on the Internet — completely exhausted.

At that exact moment, Heroku was doing the same thing in git push heroku main on its free tier. (Heroku’s free tier was retired in November 2022; Fly.io / Render / Railway now play that role.) For personal projects, “if you can’t write the reason not to use PaaS, use PaaS” is the only sane judgment. People who’ve touched both swear by it.

“Educational” and “product development” are different things. Learn infra outside work hours; ship products on PaaS. Mixing them evaporates time meant for the product. You don’t get that time back. The void after burning two days, then deploying on Heroku in 30 minutes, is the kind of feeling you only need to experience once.

“It’ll be educational” is the most expensive selection rationale. Bring it into a real project, and someone’s time melts.

What you must decide — what’s your project’s answer?

Articulate your project’s answer in 1-2 sentences for each item.

  • Application form (Native / Web / Hybrid)
  • Web service model (SaaS / PaaS / IaaS / FaaS)
  • Target platforms (Windows / Mac / iOS / Android / Linux)
  • Offline requirements
  • Performance targets (latency, throughput)
  • Distribution / update frequency and method
  • Initial cost and operating cost ceilings

These belong to project week 1. Postponing means downstream choices proceed on tentative assumptions, and major rework hits when the form is finally locked.

Common failure patterns

  • Picking SaaS just because it’s trendy — Forcing native-fitting work into the Web and dropping reputation on performance. Casual webification of video editing, 3D modeling, or large-data work hits browser limits (memory ceilings, tab crashes).
  • Native iOS / Native Android separately — 2x effort, 2x bugs. Hybrid was enough for many of these. Separate native is justified only for “1ms-fatal” domains (gaming, finance) and large companies with established native teams.
  • FaaS for always-on APIs — Cold starts shave UX. Always-on goes to PaaS. Past tens of thousands of requests/day, FaaS often loses to Cloud Run or ECS Fargate on total cost.
  • “Educational” IaaS — OS patches, certificate renewal, log rotation — all “educational.” Meanwhile the actual app moves zero millimeters. Starting on PaaS gets you to first launch 2 weeks earlier.

How to make the final call

Form cannot change later. Start by deciding “the single highest priority” and cleanly removing forms that can’t satisfy it.

Eliminate candidates that can’t satisfy physical requirements (latency, hardware control, offline), then match what remains against user demographics and dev/ops resources. Get this order wrong and a reversal will hit later.

The AI-era axis adds another lens: when two forms can satisfy the same requirements, pick the one that completes in code (Web / containers / IaC). GUI operations and custom-console dependencies stay outside AI’s reach and keep the learning cost on humans permanently. Marginal in the early 2020s, this is a first-class decision axis under AI-driven development.

Selection priority:

  1. Filter candidates by physical requirements (eliminate forms that can’t satisfy them).
  2. Decide the category by reach (worldwide browsers vs specific devices).
  3. Land on the realistic answer by dev resources (people, budget, skill).
  4. Use AI compatibility as the final differentiator.

“Just go with what’s trendy” is the most expensive selection. Form is also a statement of where you’re betting your differentiation. When in doubt, build it on the Web. Pick native only when you can write the reason on the spot.

Summary

This article covered the application form decision that comes first in system architecture.

When in doubt, Web. If the reason for native can’t be written on the spot, start with Web. Form is the most upstream irreversible decision; it deserves discussion until you can articulate it in week 1.

The next article covers the deployment model (on-prem / cloud / hybrid).

Back to series TOC -> ‘Architecture Crash Course for the Generative-AI Era’: How to Read This Book

I hope you’ll read the next article as well.