Case study 03 Publishing system · 2026

Bugnut

I fell in love with making small hand-drawn comics, then built the public reader and publishing tools I wanted as the collection grew. The site now holds 14 works and 94 pages.

Contact sheet showing a collection of hand-drawn Bugnut mini-comic covers
Artwork processed and published through Bugnut
Role
Product design
Frontend + tooling
Application
Next.js, React
TypeScript
Tooling
Node.js, Sharp
Content validation
Published collection
14 works
94 pages
01 / Purpose

The site began with the comics.

After months of drawing mini-comics, I wanted a permanent archive that felt like my work and a reader that did not get between the artwork and the person reading it. I also sell physical copies online and through local shops and events, so the site needed a direct path from reading to the shop.

The collection kept growing. Every upload meant sorting and renaming pages, resizing images, making a thumbnail, editing metadata, marking two-page spreads, and checking the finished site. The work was repetitive and gave me several chances to publish a broken page order or stale catalog entry.

I did not need a full content management system. I needed a tool that understood the folders I already exported and asked me only for information it could not work out on its own.

02 / Reader

The reader adapts to the comic and the screen.

Some pages are meant to be seen as spreads. That works on a wide screen, but shrinking two pages side by side on a phone makes the drawings hard to read. The reader groups pages differently based on the available width.

On desktop, compatible pages can open together as a spread. On a narrow screen, the same work becomes a single-page sequence. The current page is stored in the URL hash, so a reader can share or reload a specific point without an account or database.

The modal reader supports arrow keys, swipe gestures, fullscreen mode, and Escape. It traps focus while open, returns focus to the launch control when closed, and preloads the next page group so navigation feels immediate without downloading the entire comic at once.

03 / Workflow

I turned the checklist into one command.

The guided importer asks for the source folder, title, type, date, and a few optional choices. It gets the rest from the artwork.

Before
  1. Sort and rename pages
  2. Rotate and resize images
  3. Remove metadata
  4. Create a cover thumbnail
  5. Count pages and spreads
  6. Edit the site catalog
  7. Check every route
  8. Publish
Now
  1. Drop exports in a folder
  2. Run npm run add-comic
  3. Confirm detected order
  4. Answer short prompts
  5. Preview and push

What the command does

  • Sorts the input files and asks me to confirm the reading order.
  • Copies the source artwork, then writes sequential JPEG files without changing the originals.
  • Uses Sharp to rotate, flatten, resize, and remove metadata from each image.
  • Creates a gallery thumbnail and counts the pages.
  • Finds landscape pages that should be displayed as two-page spreads.
  • Updates the site catalog, sorts the work by date, and runs the content checks.
# Start the guided importer
npm run add-comic

# The build repeats validation before export
npm test
04 / Architecture

The app builds its catalog from the comic folders.

Each comic has its own folder with numbered page images and a small comic.json file. The JSON contains the title, date, and other details the script cannot learn from an image.

I do not store the page count in two places because the script can count the files. It can also create the thumbnail and detect spreads again whenever the catalog is rebuilt. The Next.js app reads the generated catalog rather than maintaining another hand-written list.

  1. Artwork folder Source exports
  2. Node pipeline Normalize + derive
  3. Next.js app Reader + galleries
  4. GitHub Pages Static delivery

A few simple conventions

Pages are named 001.jpg, 002.jpg, and so on. The importer creates those names and writes the metadata in the format the app expects. I do not have to remember the rules each time.

05 / Reliability

Bad content stops the build.

The pipeline checks slugs, dates, content types, page order, missing files, and rules for each kind of work. A one-page drawing cannot quietly contain several pages, and a comic cannot skip from 003.jpg to 005.jpg. The command stops and explains the problem before anything is published.

The production test command builds the full Next.js site and checks the rendered HTML. GitHub Actions repeats the same preparation and tests before it publishes a static export. My local preview and the live site go through the same process.

INPUT

Catch bad input before processing

The importer rejects bad paths, impossible dates, duplicate slugs, and invalid content before processing images.

TRANSFORM

Protect the source files

The tool copies the artwork and prepares it in a temporary folder. The original exports stay untouched.

BUILD

Rebuild generated files

The catalog and thumbnails can be recreated from the comic folders instead of repaired by hand.

DELIVERY

Test the finished HTML

Rendered output tests catch broken routes and markup that type checking alone would miss.

06 / Outcome

I can publish without editing the app.

Bugnut currently publishes 14 works and 94 pages. To add another, I choose its folder, answer a few prompts, check the preview, and push the result. The public reader stays fast because Next.js exports the site as static files.

I use this tool whenever I add new work, so annoying prompts and unclear errors do not stay theoretical. If part of the process wastes time, I run into it again on the next comic and have a reason to fix it.

The site is both an archive and part of the small physical-comics operation around it. Readers can move from a free digital comic to the Bugnut shop, while the same source folders and publishing checks keep the growing archive consistent.

WORKFLOW

One command replaced my checklist

The importer saved time because it replaced a checklist I was already using for every comic.

DATA

The files provide the page count

Page counts, thumbnails, and spread information stay in sync when the tool rebuilds them from the files.

ERRORS

The importer explains what failed

Useful errors tell me what failed, whether my files are safe, and what I should fix.

MAINTENANCE

Publishing is no longer a coding task

An easier publishing process makes it more likely that I will keep the site current.

Return to case study 01 Movie Master