A web-to-print shop with a browser banner designer, Stripe checkout and a Go prepress engine that turns customer artwork into PDF/X-1a files with FOGRA39 colour and 3 mm bleed.
The problem
Customer artwork for print is almost always wrong. RGB photos off a phone, no bleed, text touching the trim edge, low-resolution images, transparent drop shadows that choke the RIP. A print shop pays someone to fix every file by hand in Illustrator before it goes to the press.
The shop also wanted customers to design banners themselves, in the browser, and pay online. Birthday banners, construction-fence banners, roll-ups, stickers.
What I built
A German-language storefront with a banner designer, two sticker designers, a template catalogue, cart and checkout. Behind it, a prepress engine that takes whatever the customer uploads or designs and writes a production PDF the printer can use.
- Banner designer on Fabric.js. Templates come in six aspect-ratio variants, so photos and text carry over when the customer changes the banner size.
- Upload a PDF, JPEG or PNG and get back PDF/X-1a:2001 with a FOGRA39 output intent and 3 mm bleed.
- Stripe checkout with card and EPS, vouchers, a withdrawal form, and an admin tab where the owner edits prices without a deploy.
- AI image generation inside the designer, with daily usage caps.
- A background library of 1,256 images the owner can search by keyword.
How it works
The Go backend runs Ghostscript, QPDF, pdfcpu and Poppler in isolated per-job temp directories with timeouts and a bounded number of conversion slots. Vector PDFs are re-boxed with pdfcpu, so fonts and paths stay vectors. Bleed is generated by edge extension by default, with scale-to-cover and padding as alternatives.
Orders render the design at print size through a headless Chromium renderer, then go through the same pipeline. For each image the order picks the best source it has: SVG master first, then a print rendition, then a raster within a size budget.
The hard part was transparency. PDF/X-1a has none, so Ghostscript flattens any page that uses it into a single raster, text included. I capped flattening at 300 dpi within a 120 megapixel budget so large orders finish inside the timeout, and wrote up the trade-off for the owner and the printer to decide between PDF/X-4 and templates without transparency.
Storage is Postgres for records and content-addressed blobs for images. Every deploy takes a pg_dump first and refuses to activate on a bad one.
Outcome
The full order flow works end to end on staging. Go tests, go vet, TypeScript checks and a Vitest suite of about 1,300 tests pass. Launch is waiting on the final legal copy and the PDF/X-4 decision.
Need something like this built? contact@akhilsingh.in