AI App Builder PDF Generation in 2026: Which Builders Can Actually Produce a Document
A PDF is a rendering job, not a data format, and your backend runtime decides which of the four possible renderers you can reach. Bubble is the only one of eight with a documented path, Webflow the only one that names the constraint, and Replit the only one that can host the renderer itself.
On this page
Quick answer, September 2026. A PDF is not a data format your app writes. It is a rendering job: something has to lay out a page and turn it into a file. The eight builders here reach four structurally different renderers, and which ones you can reach is decided by your backend runtime rather than by a feature checkbox. Bubble is the only one with a first-party documented workflow action for it, and that action is a third-party API wearing a Bubble badge. Webflow is the only one whose documentation names PDF generation as an architectural constraint, and it does so to tell you which library to stop using. Replit is the only one that can host a real browser to do the rendering, and only on a deployment type that bills as a fixed monthly machine. Five of the eight publish nothing on the subject at all.
The four renderers, and why the choice is not yours
Every route to a PDF is one of these four. They are not tiers of the same thing. They fail differently, cost differently, and produce different files.
Route 1, the user's browser. A JavaScript library runs on the customer's machine and draws the document. Available on all eight, because all eight ship JavaScript to a browser. The catch is that the file is created on a machine you do not control, so your server never sees it. You cannot archive it, you cannot email it, and you cannot prove later what was in it, unless the browser uploads it back to you first.
Route 2, a pure-JavaScript library on a constrained server runtime. Libraries like pdf-lib are plain JavaScript with no native dependencies, so they run inside edge functions and Deno sandboxes. The file is made on your server. The catch is that you are laying the document out in code, coordinate by coordinate, rather than rendering the HTML page you already designed.
Route 3, a real browser on a real server. A headless Chromium renders your actual page and prints it. This is the only route where the invoice looks exactly like the invoice screen, because it is the invoice screen. The catch is that Chromium is a large binary that has to be spawned as a process, and most managed runtimes in this category cannot do either.
Route 4, a third-party rendering API. You send a URL or some HTML to a vendor and they send back a file. Works anywhere, including from runtimes that can do nothing else. The catch is that it is another vendor, another key, another bill, and the renderer has to be able to reach your page and prove who it is.
AI app builder PDF generation, compared
Scroll to see more
| Builder | Documented first-party path | Backend runtime | Route 3 reachable | What the docs actually say about PDFs |
|---|---|---|---|---|
| Yes, a Bubble-made plugin with a workflow action | Bubble's own workflow engine | No, delegated | A full page on generating PDFs, with your own third-party key | |
| No | Autoscale, Reserved VM, Scheduled, Static | Yes, on Reserved VM | Nothing on PDFs anywhere in the documentation index | |
| No | Deno serverless functions, 5 minute ceiling | No | Nothing on PDFs, but npm and jsr imports are supported | |
| No | Edge functions, written for you by the chat | No | Zero occurrences of PDF in a 57,755 character index | |
| No | Supabase edge functions, Pro and Teams, needs a database | No | Zero occurrences of PDF in its documentation index | |
| No | Vercel | Depends on your own configuration | One occurrence of PDF in 617,118 characters, and it points the wrong way | |
| No | Cloudflare Workers, 10 MB bundle, 128 MB memory | No, arithmetically | Names PDF generation in a migration table of libraries to abandon | |
| No | A sandbox with no imports and a 2 second ceiling | No | Nothing, and no library can be loaded to do it |
Webflow is the only one that says the quiet part out loud
Webflow Cloud runs framework apps on Cloudflare Workers, and its own documentation is unusually direct about what that means. It publishes a table of Node.js libraries you must replace, and one of the rows is PDF generation.
Webflow, verbatim: "PDF generation | @react-pdf/renderer | pdf-lib | Pure JavaScript implementation with no native dependencies."
That row is route 2 stated as a requirement. The same table has a row explaining why route 3 is not on the menu at all.
Webflow, verbatim: "Edge-native concurrency (stateless) | child_process, worker_threads | No process spawning or threads."
You cannot spawn a browser if you cannot spawn a process. And the published limits close the question arithmetically rather than as a matter of support: a Webflow Cloud worker is capped at a 10 MB bundle, 128 MB of memory, 30 seconds of CPU per request and a 400 millisecond cold start. A headless Chromium does not fit inside 10 MB by an order of magnitude. This is not a feature Webflow has declined to build. It is a shape of software that cannot exist in that container.
Worth noticing what this costs Webflow in a feature comparison: it scores as the builder that "cannot do PDFs" precisely because it is the only one that documented the boundary. The five builders with nothing written down score better on the same row.
Softr cannot get there at all, and the table proves it
Softr has a Run Custom Code action, which at first glance looks like a way in. Read its own reference table and the door closes.
Softr, verbatim, on what is not available in the JavaScript runtime: "require, import, fetch, top-level await (return a promise instead), console output, the file system, environment variables."
No imports means no library. No file system means nowhere to assemble a file. No fetch means you cannot even call a rendering API from there, although the runtime does expose the Node http and https modules separately. The ceilings settle the rest: synchronous JavaScript is stopped after two seconds, a returned promise must settle within five, and the Python path has no network access at all, three seconds of wall time, two of CPU, and 256 MB of memory.
That is a formula replacement, not a backend. On Softr a PDF is a route 1 or route 4 problem, and route 4 has to be driven from somewhere other than the code action.
Bubble has the only first-party path, and it is route 4 in a costume
Bubble publishes a page for a Bubble-made plugin called SelectPDF, and its opening line is the plainest statement of intent in the whole set.
Bubble, verbatim: "SelectPDF allows you to generate PDFs for your invoices, letters, and other documents."
The workflow event is called Generate PDF from a web page, and that is exactly what it does: it renders a page of your own application. It is route 3, operated by somebody else, which is route 4. Bubble says so in its setup section.
Bubble, verbatim: "After installing the SelectPDF plugin, you'll be required to add your own API keys to begin generating data."
Bubble-made does not mean Bubble-operated. You still onboard selectpdf.com, hold their key, and receive their bill. What makes this page worth reading anyway is its parameter list, which exposes a mechanic that nobody markets and that bites on every route 3 and route 4 implementation on every platform here.
Bubble, verbatim, on one of the action's parameters: "Render page as: A User of the app to run the page as."
Think about why that field has to exist. The renderer is a separate client somewhere on the internet fetching your live page. It has no session. It is not logged in as the customer who clicked the button. So it sees whatever an anonymous visitor sees, which for a private invoice is nothing at all. You have to hand it an identity, and your privacy rules then decide what it renders. Get that wrong in one direction and you produce a blank invoice. Get it wrong in the other and your renderer has broader access than any of your users.
The neighbouring parameter is the second half of the same problem. Min load time is described as "the minimum amount of time required to generate a PDF document", which in practice means you are telling a remote browser how long to wait for your own single page application to finish drawing itself. Too short and you capture a loading spinner. Too long and every document costs you seconds.
The three that publish nothing, and what their runtimes imply
Lovable, Bolt.new and Base44 all run your backend code as edge or Deno functions, and none of the three mentions PDFs.
Lovable describes edge functions as "the work that can't happen in the user's browser", which is a good definition and does not list document generation among its common use cases. Two other lines from that page matter more than the omission. Functions are not something you write: "You don't create edge functions by hand. Describe what you need in the project chat, and Lovable writes, deploys, and maintains the function for you." And they stop when the project does: "Edge functions are unavailable while a project is paused." So on Lovable the route is real but mediated, and the library choice is made by a model on your behalf.
Bolt.new routes the same work through Supabase, on Pro and Teams plans, and adds a prerequisite that is easy to miss when you are costing a feature. Bolt, verbatim: "Edge functions in Bolt rely on databases." You cannot add a document-generation function to a Bolt app that does not already have a database attached.
Base44 is the most explicit about its runtime and is therefore the easiest to reason about. Base44, verbatim: "Backend functions run on Deno, a modern TypeScript runtime." It supports npm and jsr specifiers for dependencies, which means route 2 works cleanly, and it publishes a hard ceiling that matters for batch work: "Backend functions have a maximum execution time of 5 minutes, enforced the same way whether the function is called directly, triggered by an automation, or invoked as a workflow step." Five minutes is generous for one document and thin for a month-end run of four hundred.
Replit is the only one that can host the renderer
Replit publishes four deployment types, and one of them is not like the others. Replit, verbatim: "Reserved VM Deployments run your app on a dedicated virtual machine that never sleeps."
That is the only runtime among the eight where a headless Chromium has somewhere to live: a persistent machine with a real filesystem and the ability to spawn processes. Route 3 is genuinely reachable here, and it is the route that produces a document identical to the screen.
The consequence is commercial rather than technical, and it is the kind of thing no feature matrix connects. Reserved VM bills as a fixed monthly cost rather than per request, and Replit's own comparison table pairs it with "Bots, background work, always-on APIs". So on Replit the decision to render documents properly is also a decision to move that app off usage-based pricing onto a standing machine. The other deployment types do not carry that cost and do not carry that capability either.
v0 inverts the search, exactly as it did for spreadsheets
v0's documentation is the largest in the set at 617,118 characters. The word PDF appears in it exactly once, and it is in the upload server's list of accepted file types, alongside DOCX and XLSX, under a heading about what you can paste into a chat. It is a statement about what v0 will read, not about what the app you build can produce. Puppeteer appears zero times. Chromium appears zero times.
This is the second time this pattern has shown up on the same vendor in a week: search the docs for a document format and you get hits, and every hit points at consumption rather than production. It is worth naming because it is a specific search trap rather than a general absence. A buyer who greps for PDF concludes the capability is documented. It is the opposite of documented.
None of this means a v0 app cannot make a PDF. It produces a Next.js application on Vercel, and a Next.js application can obviously render a document. The point is narrower and it is the same point as everywhere else here: nobody wrote it down, so the route is yours to choose and yours to support.
What to check before you promise someone a document
Read the runtime before you read the feature list. If your backend is an edge function or a Deno sandbox, route 3 is closed and route 2 is your realistic option, which means designing the document in code rather than reusing a page you already built. If you can reach a persistent machine, route 3 opens and the document can be the page.
Then ask the two questions the Bubble parameter list raises, because they apply to every platform here and appear in none of their marketing. Who is the renderer logged in as, and what does your permission model show that identity. And how long does your page take to be finished, given that a remote browser cannot tell the difference between still loading and nothing to show.
Finally, decide where the file goes the moment it exists. A document generated in the user's browser is not in your system, and one generated on a 30 second worker is not durable either. Both of those are storage and delivery questions rather than rendering questions, and on several of these platforms the honest answer is that a long render belongs somewhere that outlives the request that started it.
Verdict, September 2026
If you need documents that look exactly like a page you designed, Replit on a Reserved VM is the only one of the eight that can host the renderer itself, and you should price the standing machine into the decision.
If you want a documented path you can follow today without writing the renderer, Bubble is the only one that publishes one, and you should read it as an integration with selectpdf.com rather than as a Bubble feature.
If you are on Base44, route 2 is clean: Deno takes npm imports, a pure-JavaScript library will run, and you have five minutes per invocation.
If you are on Webflow Cloud, the answer is already written down for you. Use pdf-lib, lay the document out in code, and do not spend a week discovering that Chromium will not fit.
If you are on Softr, generate nothing in the code action. It cannot import a library and cannot touch a file system, so this is a client-side or external-service problem.
And on Lovable, Bolt.new and v0, the capability is almost certainly reachable and entirely undocumented. That is a support commitment rather than a blocker, and it is worth knowing which one you are signing up for.
A closing caveat that applies to all eight. Absence of a documented path is not proof that a capability is missing. It is proof that nobody wrote it down, which means you will be the person who works it out, and later the person who maintains it.
Sources
Every claim above was checked against first-party vendor documentation on 28 September 2026, and every URL returned HTTP 200 before it was cited.
- Bubble, SelectPDF plugin: https://manual.bubble.io/core-resources/bubble-made-plugins/selectpdf
- Webflow, Node.js compatibility in the Workers runtime: https://developers.webflow.com/webflow-cloud/environment/nodejs-compatibility
- Webflow, the Webflow Cloud edge environment: https://developers.webflow.com/webflow-cloud/environment
- Webflow, Webflow Cloud limits: https://developers.webflow.com/webflow-cloud/limits
- Base44, backend functions overview: https://docs.base44.com/developers/backend/resources/backend-functions/overview
- Lovable, edge functions: https://docs.lovable.dev/features/edge-functions
- Softr, Run Custom Code: https://docs.softr.io/workflows/actions/run-custom-code
- Replit, deployment types: https://docs.replit.com/features/publishing/deployment-types
- Bolt.new, Supabase integration: https://support.bolt.new/integrations/supabase
- v0, documentation index: https://v0.app/docs/llms.txt
Method note on the occurrence counts. The v0 figure is taken from its full-content documentation index, so a zero there is a strong claim about the corpus. The Lovable, Bolt.new, Replit, Base44 and Softr indexes are lists of page titles and descriptions rather than full bodies, so a zero there means no page is titled or described around the subject, which is a weaker claim and is stated as such in the table. Known-positive controls fired on every index that returned a zero.
Written by
Builderdex EditorialFrequently asked questions
Can every AI app builder generate a PDF?
Every one of the eight can produce a PDF in the user's browser, because all eight ship JavaScript to a browser. What differs is whether your server can make the file. That depends on the backend runtime rather than on a feature list, and on five of the eight the vendor documents nothing about it either way.
Which AI app builder has a documented PDF feature?
Bubble is the only one of the eight with a first-party documented path. Its Bubble-made SelectPDF plugin adds a Generate PDF from a web page workflow action. Read it as an integration rather than a Bubble feature: the setup section requires you to add your own selectpdf.com API key, so you hold that vendor relationship and that bill.
Why can Webflow Cloud not generate PDFs with a headless browser?
Webflow Cloud runs framework apps on Cloudflare Workers, and its published limits cap a worker at a 10 MB bundle, 128 MB of memory and 30 seconds of CPU. Its compatibility table also states that child_process and worker_threads are unavailable, with the note No process spawning or threads. A headless Chromium neither fits in 10 MB nor can be spawned, so the route is closed by arithmetic rather than by policy.
Can Softr generate a document in its custom code action?
No. Softr's own reference table lists require, import, fetch, top-level await, console output, the file system and environment variables as not available in the JavaScript runtime. With no imports you cannot load a PDF library, and with no file system you have nowhere to assemble a file. Synchronous JavaScript is also stopped after two seconds. On Softr this is a client-side or external-service problem.
Which builder can host a real headless browser for rendering?
Replit, on a Reserved VM deployment, which its documentation describes as a dedicated virtual machine that never sleeps. That is the only runtime among the eight with a persistent filesystem and the ability to spawn processes. The trade is commercial: Reserved VM bills as a fixed monthly machine rather than per request.
Why does a PDF renderer need to be told which user to run as?
Because the renderer is a separate client fetching your live page and it has no session. Bubble's plugin exposes this directly with a parameter described as a User of the app to run the page as. If you give it the wrong identity your privacy rules either hide the data, producing a blank document, or show it too much. The same problem applies to any third-party rendering service on any platform.
Do Lovable, Bolt.new and v0 support PDF generation?
None of the three documents it. PDF occurs zero times in Lovable's and Bolt.new's documentation indexes, and exactly once in v0's 617,118 character index, where it appears in the list of file types you can upload into a chat rather than anything the built app produces. All three can almost certainly do it, since they generate ordinary web applications. The point is that the route is undocumented, so it becomes yours to choose and yours to maintain.
Related comparisons
AI App Builder Built-In Payments (2026): Who Ends Up in Your Money Path?
Every AI app builder can take a payment. The real question is who becomes the legal seller and who takes a cut first. A primary-source comparison of eight builders sorted into four money-path tiers, from own-processor to merchant of record to app-store billing.
AI App Builder File Storage (2026): Where Your Uploads Live
Every AI app builder accepts a file. Almost none of them store it where you think. Eight builders compared on whose bucket holds the bytes, whether a file URL is the only permission protecting it, and what survives a delete, an export and a move.
AI App Builder Database Portability (2026): Where Your Data Lives and How It Gets Out
A criteria-based 2026 scorecard of database portability across six AI app builders: v0, Bolt.new, Lovable, Replit, Base44, and Bubble. Whose account holds the data, who gives you a connection string, and why a CSV export is not the same as a portable database.