Why We Separated Marketing from Product

How deliberate architectural boundaries between marketing and boilerplate code produce a cleaner customer experience.

The problem with boilerplate that includes everything

Most SaaS boilerplates ship their marketing site alongside the product code. The pitch sounds reasonable: "You get everything — landing pages, pricing tables, blog, dashboard. Delete what you do not need."

The problem is that nobody knows what is safe to delete.

Marketing components import shared utilities. Shared utilities are used by dashboard components. CSS classes defined for landing page animations might be referenced in the Tailwind configuration that your product depends on. After an hour of tracing imports and testing deletions, you start wondering whether ripping out the marketing code will break something in production that you will not discover until a customer reports it.

This is not a theoretical concern. Every hour a customer spends auditing code they did not ask for is an hour they are not building their actual product. And that cleanup tax compounds — every future dependency update, every refactor, every new hire onboarding session has to navigate around code that was supposed to be "just delete it."

We decided this was the wrong default.

Our separation strategy

nextsaas.ai uses a monorepo architecture with Turborepo and pnpm workspaces. The product and the marketing site live in completely separate applications:

AspectTypical Boilerplatenextsaas.ai Approach
StructureSingle app with everythingapps/boilerplate/ + apps/marketing/
DependenciesShared, often tangledScoped per application
BuildOne build, one bundleIndependent builds, parallel execution
Component leakageMarketing components importable anywhereEnforced scope boundaries
Customer cleanupHours of manual deletionZero — they get only the product
Dev serverSingle port, everything loadsSeparate ports, start only what you need

The key insight is that separation is not just about file organization. It is about dependency isolation. When marketing and product are separate applications with separate package.json files, separate build configurations, and separate deployment targets, there is no way for marketing code to accidentally become a dependency of the product.

Scoped packages in practice

Shared code between the two applications goes through explicitly scoped packages. The UI component library uses a scope system that controls which components are available to which application:

  • @nextsaasai/ui/boilerplate exports components designed for the product dashboard — data tables, form layouts, settings panels.
  • @nextsaasai/ui/marketing exports components designed for the marketing site — hero sections, feature grids, testimonial cards.
  • @nextsaasai/ui/shared exports components that are genuinely cross-cutting — buttons, badges, tooltips, theme primitives.

The bar for "shared" is deliberately high. A component only lands in the shared scope when both applications genuinely need the exact same implementation. When in doubt, we duplicate rather than share, because a false dependency between marketing and product is worse than a few lines of repeated code.

This is enforced at the import level. apps/boilerplate/ cannot import from @nextsaasai/ui/marketing, and apps/marketing/ cannot import from @nextsaasai/ui/boilerplate. The boundary is structural, not just a convention that someone might accidentally violate during a late-night coding session.

The delivery pipeline

When a customer receives nextsaas.ai Kit, they get a clean monorepo workspace. The delivery pipeline automatically strips marketing-specific applications and configurations while preserving the full workspace structure that the product depends on.

This means customers start with a workspace that contains their product, the shared packages it needs, and nothing else. No leftover marketing routes to confuse their routing. No unused marketing dependencies inflating their node_modules. No marketing CSS competing with their product styles.

The delivery pipeline runs automated checks to verify that the customer package builds independently, all tests pass, and no references to removed marketing code remain. A customer should be able to run pnpm install and pnpm dev immediately after receiving their package, without any cleanup step.

What clean architecture enables

The architectural boundary between marketing and product is not just about code cleanliness. It is a form of respect for the customer's time and attention.

When a developer starts building on a boilerplate, their first experience shapes their confidence in the entire codebase. If that first experience involves figuring out which files to delete and which to keep, the implicit message is: "We built this for ourselves first and adapted it for you second." If the first experience is a clean workspace where every file is relevant to their goals, the implicit message is different: "We built this for you."

This separation also enables something practical that matters as the project grows. Marketing can ship new landing pages, blog posts, and documentation updates without affecting the product. The product can receive new features, security patches, and dependency upgrades without touching marketing. Independent release cycles mean faster iteration and less risk for both sides.

Architectural decisions are product decisions. The way you organize code communicates what you value. We chose to value the customer's experience from the first pnpm install forward.