<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: PingClass</title>
    <description>The latest articles on DEV Community by PingClass (@pingclass_off).</description>
    <link>https://dev.to/pingclass_off</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4136030%2F81068b0d-eeee-4243-afdf-395dbc8c411d.png</url>
      <title>DEV Community: PingClass</title>
      <link>https://dev.to/pingclass_off</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/pingclass_off"/>
    <language>en</language>
    <item>
      <title>I built a tuition management SaaS with plain HTML, Supabase and Vercel</title>
      <dc:creator>PingClass</dc:creator>
      <pubDate>Mon, 21 Sep 2026 15:50:44 +0000</pubDate>
      <link>https://dev.to/pingclass_off/i-built-a-tuition-management-saas-with-plain-html-supabase-and-vercel-4o91</link>
      <guid>https://dev.to/pingclass_off/i-built-a-tuition-management-saas-with-plain-html-supabase-and-vercel-4o91</guid>
      <description>&lt;p&gt;I spent a few weeks building PingClass — institute-management software for small tuition and coaching centers in India (1–5 teachers, under ~200 students). The kind of businesses that still run on a patchwork of Google Sheets, paper registers, and four WhatsApp groups.&lt;/p&gt;

&lt;p&gt;The interesting part isn't the product though, it's how it's built: no framework, no frontend build step, static HTML files, a Postgres database, and a free CDN. I want to share the stack and what I learned, because this is the least-discussed way to ship a SaaS that runs and ranks.&lt;/p&gt;

&lt;p&gt;The constraints that pushed me here&lt;br&gt;
I'm a solo maker shipping in evenings. I didn't want a toolchain I have to babysit.&lt;br&gt;
The customers are offline-first small business owners. They open a link, it should just work, load fast, and not break.&lt;br&gt;
I wanted the site's marketing pages to be instantly crawlable by Google, Bing, and the AI search bots — static HTML is the most undisputed, indexable thing that exists.&lt;br&gt;
The stack&lt;br&gt;
Static HTML + vanilla JS   -&amp;gt;  Vercel (free tier, global CDN)&lt;br&gt;
Supabase (Postgres + Auth) -&amp;gt;  tenant data, users, reviews&lt;br&gt;
JSON-LD structured data    -&amp;gt;  SEO / AI answer engines&lt;br&gt;
llms.txt                   -&amp;gt;  explicit signal for AI crawlers&lt;br&gt;
IndexNow                   -&amp;gt;  instant Bing re-crawl on deploy&lt;br&gt;
Why static HTML&lt;br&gt;
Every page is a real .html file. There's no hydration, no #app shell, no client routing. Googlebot, ClaudeBot, PerplexityBot and GPTBot all just read the HTML — headings, text, structured data — directly. The marketing site lives in the most defensible form SEO can have.&lt;/p&gt;

&lt;p&gt;The interactive parts (auth, dashboards) are separate static pages that talk to Supabase with client-side JS.&lt;/p&gt;

&lt;p&gt;Supabase for everything data&lt;br&gt;
A single Supabase project handles:&lt;/p&gt;

&lt;p&gt;Postgres — core tables: students, batches, attendance, fees, announcements, parents.&lt;br&gt;
Auth — email-based sign-in with admin/teacher/parent roles.&lt;br&gt;
RLS policies — row-level security so an institute only ever sees its own rows, enforced at the database level.&lt;br&gt;
The fee module auto-generates monthly dues per student × batch and lets owners send due reminders — that's where the "fewer spreadsheets" pitch actually lands.&lt;/p&gt;

&lt;p&gt;One query the site runs for its public reviews section:&lt;/p&gt;

&lt;p&gt;const { data: reviews } = await supabase&lt;br&gt;
  .from('reviews')&lt;br&gt;
  .select('author_name, quote, rating, institute')&lt;br&gt;
  .eq('status', 'approved')&lt;br&gt;
The tricky bit: reviews are loaded client-side, so they'd be invisible to crawlers. I solved it by rendering the approved reviews as static HTML on the homepage too, and having JS skip authors that are already statically present. Same for the aggregateRating structured data — crawlers get the facts front-and-center.&lt;/p&gt;

&lt;p&gt;What I'd do differently (maybe)&lt;br&gt;
Payment gateway. Ledgers and reminders work; actual collection is still manual. A Razorpay integration is the next obvious wedge.&lt;br&gt;
Mobile app. Parents want an app. Web-first was the right place to start, but "Is there an app?" is the #1 question.&lt;br&gt;
Validate before building as much. The fee/attendance/parent-communication triangle seems right, but I'd have liked real signed-up centers earlier rather than a polished product first.&lt;br&gt;
The meta-lesson&lt;br&gt;
You don't need React + a queue system + Kubernetes for a tool that two dozen tuition centers might use. Static HTML + a managed Postgres + a CDN handled everything, cost almost nothing, and made the "will people find it?" problem dramatically easier — because every page is HTML that search engines and LLMs read natively.&lt;/p&gt;

&lt;p&gt;If you're building a small vertical SaaS and feel the pull toward a heavier stack, ask whether the extra machinery earns its keep.&lt;/p&gt;

&lt;p&gt;PingClass is live — free tier up to 20 students, then ₹249/mo and ₹599/mo. As also featured on Product Hunt and G2. Happy to answer questions about the stack or the tuition-center niche.&lt;/p&gt;

</description>
      <category>database</category>
      <category>saas</category>
      <category>startup</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
