Loading spinner
Dan Edwards Developer icon

Dan Edwards developer

5 June 2025Live siteGitHub

Simple Order

simpleorder.co.uk

Simple Order

Overview

Small wholesale businesses, such as bakeries, florists, and timber merchants, often struggle with order management.

Many rely on phone calls, Excel spreadsheets, scraps of paper, or even their memory because existing software solutions are complicated and cost up to £150 per month.

Since January 14, 2025, I have developed Simple Order to create a blue ocean in this underserved market with an affordable, intuitive order management platform priced at just £20 per month.

/demo/orders/janes-bakery/new

Screenshot of Simple Order wholesale order management website in demo mode, showing the creation of a new order from a bakery

Inspiration

Two years ago, my mum bought a village shop, and through her experiences with various B2B companies, I've gained insider insight into the frustrations of existing solutions.

Most suppliers she works with still take orders by phone because the current software offerings are either too expensive or too complex for their needs.

This represents a classic blue ocean opportunity: creating uncontested market space by serving businesses that don't currently use software rather than convincing people to switch over from alternatives.

Blue Ocean Strategy audiobook cover

Key innovation: Comprehensive demo

Instead of requiring users to sign up before seeing the product, I've built a sophisticated demo system that showcases the product's full functionality without interacting with the database.

This solves the friction problem I identified across 20+ competitors, as none of them offer immediate product exploration.

The architecture utilises shared components (such as InventoryPageContent) that accept props for data and functions, which are called from both live routes (/inventory) and demo routes (/demo/inventory).

The live version uses functions that interact with the database, whereas the demo uses client-side data only, with subtle delays to emulate a network request. This provides an authentic user experience while keeping the code incredibly DRY.

Here's a simplified example:

/app/inventory/page.tsx
TypeScript
function InventoryPage() {
	// real data & database functions
  const { products, addProduct } = useInventory();

  return (
    <InventoryPageContent
      products={products}
      addProduct={addProduct}
    />
  );
}
/app/demo/inventory/page.tsx
TypeScript
function DemoInventoryPage() {
	// client-side data without persistence
  const { products, addProduct } = useDemoInventory();

  return (
    <InventoryPageContent
      products={products}
      addProduct={addProduct}
    />
  );
}
/component/InventoryPageContent.tsx
TypeScript
// The entire page is a presentational component
function InventoryPageContent({
  products,
  addProduct,
}: {
  products: Product[];
  addProduct: (product: Product) => boolean;
}) {
  return (
    <>
      <InventoryList products={products} />
      <InventoryForm addProduct={addProduct} />
    </>
  );
}

Programmatic content generation

I've implemented programmatic content generation targeting 47 specific industries, using my background in SEO content writing to create high-quality articles that cater to businesses such as artisan food producers, craft breweries, and speciality manufacturers.

These articles are hidden from the /articles page but are listed in the sitemap.xml.

This strategy is already showing results - according to Search Console data, the site was ranking on the second page of Google results for several key terms just one week after implementation.

Screenshot of a programmatic article entitled "Affordable firewood supplier order management software"

I've identified 47 industries that can use Simple Order, so each article becomes 47 targeted variations like this firewood supplier example.

Product-led growth strategy

Inspired by books such as Product-Led Growth, The Lean Startup, and Blue Ocean Strategy, I've designed Simple Order around immediate value delivery:

How it works

  • Friction-free trials

    Wholesalers start immediately without credit card details

  • Fast onboarding

    Users can add their inventory and customers in minutes

  • Elegant order management

    Clean interfaces for order placement and fulfilment

  • PDF invoice generation

    Quickly print or save generated invoices, eliminating manual paperwork

  • Multi-currency support

    Localised experiences at /usd, /eur, and /cad, etc., with middleware-based location detection and redirection

simpleorder.co.uk/nzd

The Simple Order website pricing section showing currencies in New Zealand dollars.

Deliberately avoided features

Following blue ocean principles, I've omitted complexity that doesn't add value:

  • No payment processing

    Merchants prefer direct bank transfers to avoid fees

  • No product photos

    Merchants have product marketing brochures already

  • No delivery management

    This isn't a pain point for most small wholesalers

  • No order confirmation emails

    Browser/database confirmation is sufficient and more reliable

Diagram showing Next.js framework architecture with connections to libraries including React.js, Link, Image, Router and CLI.

Next.js has a steep learning curve but rewards the investment by enabling web applications that excel in both user experience and business metrics.

Architecture highlights

  • Next.js

    The full-stack framework built on top of React, deployed with Vercel

  • Hybrid rendering

    Static generation for SEO-critical pages, SPA experience for applications

  • React-email for stylish transactional emails

  • Multi-currency infrastructure

    Automatic routing and localisation using Vercel’s edge network headers

  • Sophisticated forms

    Zod validation with React Hook Form for seamless user experiences at critical conversion points

  • End-to-end type safety

    Custom API system ensuring predictability across the stack using TypeScript discriminated unions

Simplified type-safe end-to-end API example
TypeScript
// Type-safe API with discriminated unions
type APIResponse<T> = 
  | { ok: true; data: T }
  | { ok: false; userMessage: string }

export async function GET(): Promise<APIResponse<Order[]>> {
  // Implementation ensures strict type safety
}

// The client knows that data & userMessage can't exist at the same time
const { ok, data, userMessage } = await apiRequest<OrdersGETresponse>({path: "/orders"})

Performance

All public-facing pages have perfect or near-perfect Lighthouse scores, thanks to the use of optimised images, dynamic imports, and strategic code splitting.

Chrome Lighthouse scores for SimpleOrder.co.uk, showing perfect results across the board

Database & integrations

  • PostgreSQL with Drizzle ORM deployed with Neon
  • Stripe API for subscriptions
  • MailGun with React-email for transactional emails
Stripe-hosted checkout page for a Simple ORder wholesale order management subscription

Continuous learning

Throughout the process, my continuous learning in code, design, marketing, and business strategy has shaped my approach to SaaS development.

After struggling with MongoDB schemas, I read Designing Data-Intensive Applications and discovered the elegance of relational databases, which has dramatically improved my development speed and confidence.

Similarly, studying the principles from Refactoring UI guided the creation of a minimal, blue-accented interface that reinforces the brand's promise of simplicity.

Conclusion

Simple Order has been an immensely gratifying project. While the business concept has potential, the principal value for me has been in what I've learned: strengthening my full-stack and product development skills, acquiring auxiliary knowledge along the way, and creating a project that demonstrates my ability to translate user needs into technical solutions.