Worksheet Boss

Print-ready classroom worksheets from a topic, in seconds

Status
LiveLive at worksheetboss.com on Firebase Hosting; last deployed July 2026
Platforms
Web
Role
Solo: product, design, front end, Firebase back end, payments
Timeline
May 2023 – Nov 2026131 commits

01 The story

A web app for teachers: type a topic, pick a grade, subject and question style, and get a print-ready worksheet with an answer key, as PDF or Word. I started it in 2023 on GPT-3.5; it now runs on Gemini behind a Cloud Function, with Stripe plans and monthly limits enforced on the server.

I started WorksheetWizard in May 2023, a few months after ChatGPT arrived, to save teachers the job of hand-making worksheets. The first version was a Firebase-hosted site on a Bootstrap template: a form for topic, grade, subject, question type, difficulty and count, a call to OpenAI's gpt-3.5-turbo, and the result rendered as a worksheet you could download as a Word file. Within two weeks it had Google sign-in, plan tiers and a new name, SheetBoss.

Through summer 2023 it grew a saved-worksheet collection, a gallery for teachers' uploads, a Stripe payment page, dark mode, monthly usage resets and a new worksheet template. In November 2024 I moved generation from OpenAI to Google's Gemini with a reworked prompt. In 2026 I rewrote the whole site as Worksheet Boss, dropping the template, jQuery and Bootstrap for a small hand-written 'paper and ink' design system: cream paper, a teacher's red-pen accent and ruled-line blue.

The biggest change is where the trust boundary sits. The 2023 site called the AI and checked usage limits from the browser, which anyone could bypass. Now the studio calls /api/generate, which Firebase Hosting rewrites to a Cloud Function. It verifies the user's Firebase ID token, checks the request origin, reserves one generation atomically against the monthly limit for the user's tier, and calls Gemini with a key held in Secret Manager. Tiers are read-only to clients and set by a function that watches Stripe subscription records.

The model returns structured JSON against a schema for ten question types, and the browser renders it as a printable sheet with answer bubbles, matching columns and writing lines. The rewrite is live at worksheetboss.com with a free tier and three paid tiers. Its source sits on a snapshot branch recovered from the SSD in November 2026; the main branch still holds the 2023 to 2024 version.

02 What it does

  1. 01

    Generate a worksheet from a topic, grade band, subject, question style, difficulty and length

  2. 02

    Ten question types, from multiple choice, true/false and fill-in-the-blank to matching, short answer, essay and reading comprehension

  3. 03

    Optional answer key, generated alongside the questions

  4. 04

    Print directly, or download as PDF or Word (.docx)

  5. 05

    Personal library of saved worksheets and a page of example worksheets

  6. 06

    Email or Google sign-in; one free guest worksheet before signing up

  7. 07

    Free plan plus Starter, Pro and School subscriptions with monthly worksheet allowances

  8. 08

    Light and dark themes

03 How it's built

AppStatic site (studio, library, pricing)
Outside serviceStripe
ServiceFirebase Auth
ServiceCloud Function: api (Gemini proxy + quota)
ServiceCloud Function: syncTier
ModelGemini 3.1 Flash-Lite
DataRealtime Database

The browser never holds the AI key: generation goes through an authenticated Cloud Function that enforces plan limits server-side. Stripe subscription changes flow into a tier field that only the server can write.

All 7 connections, as text
  • Static site (studio, library, pricing) → Firebase Auth: sign in
  • Static site (studio, library, pricing) → Cloud Function: api (Gemini proxy + quota): POST /api/generate + ID token
  • Cloud Function: api (Gemini proxy + quota) → Realtime Database: reserve monthly quota
  • Cloud Function: api (Gemini proxy + quota) → Gemini 3.1 Flash-Lite: schema-constrained JSON
  • Stripe → Cloud Function: syncTier: subscription records
  • Cloud Function: syncTier → Realtime Database: set tier
  • Static site (studio, library, pricing) → Realtime Database: save worksheets

04 Engineering notes

  • Gemini key kept server-side: Firebase Hosting rewrites /api/generate to a Cloud Function that verifies ID tokens, checks an origin allowlist and reads the key from Secret Manager

  • Per-tier monthly quotas reserved atomically with a Realtime Database transaction (users/{uid}/usage/{YYYY_MM}); rules stop clients from upgrading their own tier

  • Stripe subscriptions mapped to plan tiers by a Firestore-triggered function (syncTier)

  • Structured output: a JSON schema for ten question types with prompt rules for plausible distractors and grade-appropriate wording, rendered client-side into printable 'paper' HTML

  • Exports via jsPDF and html-docx-js; the 2023 version built .docx files in the browser with the docx library

  • Migrated across three models: gpt-3.5-turbo (2023), Gemini 1.5 Flash (2024) and Gemini 3.1 Flash-Lite (2026)

05 By the numbers

10
Question types
4
Plans: Free (10 a month), Starter $1.50 (100), Pro $2.50 (500), School $5 (2,000)

06 Stack

App

  • HTML
  • CSS (custom design system)
  • Vanilla JavaScript
  • Firebase JS SDK v12
  • jsPDF
  • html-docx-js
  • Fraunces / Instrument Sans

Backend

  • Firebase Cloud Functions (v2)
  • Google Gemini 3.1 Flash-Lite
  • Stripe subscriptions (Firebase Stripe extension)

Data

  • Firebase Realtime Database (worksheets, usage, tiers)
  • Firestore (Stripe customers and subscriptions)

Infrastructure

  • Firebase Hosting
  • Secret Manager
  • GitHub Actions (hosting preview deploys)

Tooling

  • Firebase emulators
  • Python http.server for static preview

Lines of code (approx.)

  • JavaScript1,653
  • HTML1,437
  • CSS702

≈ 3,792 lines

Repositories

  • WorksheetWizardprivate

Main branch: active May to July 2023, with small updates in August 2024 and November 2024 (the move to Gemini). I never committed the 2026 rewrite during development; I recovered it from the SSD and committed it on 2026-11-09 to branch ssd-snapshot-2026-11-09. The live site's Last-Modified header is 2026-07-07.