<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Browser-Based PDF Merge: Why I Chose the Browser First for pdfzus]]></title><description><![CDATA[Browser-Based PDF Merge: Why I Chose the Browser First for pdfzus]]></description><link>https://yxchen1994.hashnode.dev</link><image><url>https://cdn.hashnode.com/uploads/logos/69b5243c210c74252fd5b0da/aa9f5ccb-ffeb-4ea8-a0ef-89e4afd6d25a.png</url><title>Browser-Based PDF Merge: Why I Chose the Browser First for pdfzus</title><link>https://yxchen1994.hashnode.dev</link></image><generator>RSS for Node</generator><lastBuildDate>Wed, 16 Sep 2026 03:17:29 GMT</lastBuildDate><atom:link href="https://yxchen1994.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Browser-Based PDF Merge: Why I Chose the Browser First for pdfzus]]></title><description><![CDATA[If you have ever thought about building an online PDF merge tool, the first version of the idea probably sounds almost trivial: pick a PDF library, upload a few files, combine them, and download the r]]></description><link>https://yxchen1994.hashnode.dev/browser-based-pdf-merge-why-i-chose-the-browser-first-for-pdfzus</link><guid isPermaLink="true">https://yxchen1994.hashnode.dev/browser-based-pdf-merge-why-i-chose-the-browser-first-for-pdfzus</guid><category><![CDATA[webdev]]></category><dc:creator><![CDATA[YUXIANG CHEN]]></dc:creator><pubDate>Sat, 14 Mar 2026 09:20:49 GMT</pubDate><content:encoded><![CDATA[<p>If you have ever thought about building an online PDF merge tool, the first version of the idea probably sounds almost trivial: pick a PDF library, upload a few files, combine them, and download the result.</p>
<p>That is not the real problem.</p>
<p>When I started shaping <code>pdfzus</code>, I realized the hard part was not “can I merge PDFs?” The hard part was deciding where that merge should happen, what kind of workloads the product should support, and how much of the UX should be constrained by privacy rather than by backend convenience. That is why I chose a browser-based PDF merge architecture first. It gave me a stronger privacy model and a more direct user experience, but it also forced me to be much more honest about limits.</p>
<img src="https://cdn.hashnode.com/uploads/covers/69b5243c210c74252fd5b0da/4a62580e-f5fc-499e-94b8-73f1c78e2dfe.png" alt="" style="display:block;margin:0 auto" />

<h2>The real question is not “can the browser do it?”</h2>
<p>The obvious engineering question is whether the browser can merge PDFs at all. Today, that part is no longer especially controversial. The repo already reflects the building blocks clearly: <code>pdf-lib</code> is present for document manipulation, <code>pdfjs-dist</code> is present for rendering-related tasks, and <code>@dnd-kit/*</code> is present for drag-and-drop interactions. React and Next.js handle the surrounding application structure.</p>
<p>So the browser can do it.</p>
<p>The more important question is whether the browser should do it for your product.</p>
<p>That is where I think a lot of PDF tool discussions go wrong. Developers often reduce the architecture decision to a capability question: “Can I make this work locally?” But for a real product, the better question is: “What complexity am I accepting if I do?”</p>
<p>That distinction mattered <a href="https://pdfzus.de/">pdfzus</a>. I was not trying to build a giant document platform. I wanted a privacy-friendly PDF tool for a narrow but common workflow: import multiple PDFs, order them clearly, merge them, and hand the user back one clean file.</p>
<h2>Why I chose the browser first</h2>
<p>I chose the browser first because the core workflow benefits directly from local processing.</p>
<p>People do not only merge throwaway PDFs. They merge resumes, certificates, forms, administrative paperwork, study materials, and internal business documents. Once I framed the problem that way, the architecture choice became less abstract. Sending those files to a third-party server might be acceptable for some tools, but it was not the product story I wanted for <code>pdfzus</code>.</p>
<p>Local processing gave me three practical advantages.</p>
<p>First, it improved the privacy model. A browser-based PDF merge flow makes it easier to say, with technical backing, that the document handling is local to the user’s environment.</p>
<p>Second, it reduced backend responsibility. I did not need to begin with upload pipelines, temporary document storage, merge queues, cleanup policies, and all the security questions that come with them.</p>
<p>Third, it made the interaction model better for this specific job. The workflow is inherently visual: add files, change their order, check the set, export. That maps well to a browser UI, especially when ordering is implemented as a real drag-and-drop interaction rather than a table full of “move up” buttons.</p>
<p>This is where <code>@dnd-kit/*</code> matters more than it might seem. In a browser-based PDF merge tool, drag-and-drop ordering is not polish. It is part of the core problem. If ordering feels weak, the entire workflow feels weak.</p>
<h2>The stack is simple, but the decision is not</h2>
<p>On paper, the stack is not unusual.</p>
<ul>
<li><p><code>pdf-lib</code> handles core PDF manipulation tasks.</p>
</li>
<li><p><code>pdfjs-dist</code> supports rendering and document-facing UI needs.</p>
</li>
<li><p><code>@dnd-kit/*</code> supports ordering and interaction.</p>
</li>
<li><p>React and Next.js hold the product together.</p>
</li>
</ul>
<p>That is a practical stack for a browser-based PDF merge tool. But the decision is not just about libraries. It is about choosing the kind of product you are willing to build.</p>
<p>I think that is the non-obvious part.</p>
<p>A browser-first architecture is not simply the “more modern” option. It is a constraint system. It pushes you toward a certain product shape:</p>
<ul>
<li><p>lighter document workflows</p>
</li>
<li><p>strong emphasis on immediate interaction</p>
</li>
<li><p>narrower feature boundaries</p>
</li>
<li><p>more explicit handling of edge cases</p>
</li>
</ul>
<p>That can be a strength. It can also be a trap if you keep pretending the browser is a general-purpose PDF infrastructure layer.</p>
<h2>Where browser-side merge works extremely well</h2>
<p>For everyday merge flows, I still think the browser is the right place.</p>
<p>If someone needs to combine a cover letter, resume, and certificates into one application PDF, the browser works well. If a user needs to merge a set of office attachments into one document before sending an email, the browser works well. If the main value is local ordering, fast feedback, and not having to trust an upload-heavy workflow, the browser works well.</p>
<p>That is the sweet spot I had in mind for <code>pdfzus</code>.</p>
<p>The architecture fits that workflow because the job is relatively narrow:</p>
<ol>
<li><p>load files</p>
</li>
<li><p>preview or understand the set</p>
</li>
<li><p>reorder them</p>
</li>
<li><p>merge them</p>
</li>
<li><p>export one result</p>
</li>
</ol>
<p>The tighter the workflow, the stronger the browser-first decision becomes.</p>
<p>This is also where <code>pdfjs-dist</code> earns its place. Merge is not only about the output. It is also about helping users understand what they are merging. Once a tool starts handling multiple documents with ordering, visual context stops being a nice-to-have and becomes part of usability.</p>
<h2>What I got wrong at first</h2>
<p>My initial assumption was that moving PDF merge into the browser would make the system simpler overall.</p>
<p>That was only half true.</p>
<p>It simplified some parts of the system. It did not simplify the product as a whole.</p>
<p>The complexity moved.</p>
<p>Instead of backend pipelines and storage management, I had to think much harder about browser constraints: memory pressure, file size boundaries, encrypted documents, and the fact that users do not care whether a limitation is caused by the runtime or by my product decisions. They only care that the workflow feels reliable.</p>
<p>That was the real correction in my thinking: browser-side processing does not remove complexity; it relocates it.</p>
<p>And once you accept that, your architecture decisions get better.</p>
<p>You stop asking “can the browser technically do this?” and start asking “is this still the right runtime for the user experience I want to defend?”</p>
<p>That is a much more useful question.</p>
<h2>The browser is not the right home for every PDF workload</h2>
<p>I would absolutely choose browser-side merge again for <code>pdfzus</code>, but I would not recommend it blindly for every PDF product.</p>
<p>It works well when:</p>
<ul>
<li><p>the workflow is mostly merge, order, and export</p>
</li>
<li><p>the documents are light to medium in complexity</p>
</li>
<li><p>privacy is part of the product value</p>
</li>
<li><p>direct interaction matters more than backend orchestration</p>
</li>
</ul>
<p>It becomes a weaker fit when:</p>
<ul>
<li><p>the files are very large</p>
</li>
<li><p>the workload becomes heavy batch processing</p>
</li>
<li><p>encrypted documents or unusual PDF structures are common</p>
</li>
<li><p>users expect enterprise-style document handling at scale</p>
</li>
</ul>
<p>The repo and research docs already point in that direction. There is repeated discussion around <code>pdf-lib</code> being a strong fit for browser-side merge and page operations, while large files, encrypted PDFs, and more advanced operations push the architecture toward other paths such as WebAssembly-heavy engines, server-side fallbacks, or hybrid designs.</p>
<p>That is another place where I want to be careful. It is easy to take the existence of WebAssembly-related docs and overstate current production detail. I do not want to do that. For this article, WebAssembly is part of the architectural context and design direction around local processing, not a place for me to claim unverified implementation specifics.</p>
<h2>What I would do differently in v2</h2>
<p>If I were designing the next iteration from scratch, I would make the architecture boundaries even more explicit earlier.</p>
<p>I would define, in the product itself, what browser-side merge is for and what it is not for.</p>
<p>That means:</p>
<ul>
<li><p>clearer file-size and workload expectations</p>
</li>
<li><p>more obvious messaging around unsupported or high-risk edge cases</p>
</li>
<li><p>a more deliberate path toward hybrid handling if the product scope expands</p>
</li>
<li><p>stricter separation between “fast local workflow” and “heavy document processing”</p>
</li>
</ul>
<p>I think many browser-based tools wait too long to make those boundaries visible. They try to preserve the illusion that one architecture can gracefully own every scenario. In practice, that tends to create worse UX, not better architecture.</p>
<p>The lesson I took from <code>pdfzus</code> is that users trust focused tools more than vague tools. And architecture is part of that trust.</p>
<h2>My practical advice for developers building this kind of tool</h2>
<p>If you are considering a browser-based PDF merge product, I would use these filters.</p>
<p>Choose the browser first if:</p>
<ul>
<li><p>privacy is central to the product story</p>
</li>
<li><p>your workflow is mostly interactive and lightweight</p>
</li>
<li><p>drag-and-drop ordering and direct manipulation matter</p>
</li>
<li><p>you want to avoid backend file infrastructure in the early product</p>
</li>
</ul>
<p>Choose server-side or hybrid earlier if:</p>
<ul>
<li><p>large documents are normal</p>
</li>
<li><p>encrypted files are common</p>
</li>
<li><p>batch workloads are part of the core use case</p>
</li>
<li><p>you need broader PDF operations than merge-focused flows</p>
</li>
</ul>
<p>Most importantly, do not frame the browser as a universal solution. Frame it as a deliberate strategy for a particular kind of document workflow.</p>
<p>That is the architectural decision behind <code>pdfzus</code>. Not “the browser can do PDF merging,” but “for this problem, the browser is the right first runtime.”</p>
<h2>Conclusion</h2>
<p>A browser-based PDF merge tool is not interesting because it avoids a server. It is interesting because it forces a more disciplined product architecture.</p>
<p>For <code>pdfzus</code>, choosing the browser first made sense because the workflow is focused, privacy matters, and direct ordering is part of the job itself. The tradeoff is that I have to treat runtime limits as first-class design constraints, not as hidden technical debt.</p>
<p>That is the real takeaway I would give another developer: if you want to merge PDFs in the browser, do it because the product shape justifies it, not because local processing sounds cleaner on paper.</p>
<p>When the fit is right, it leads to a better tool. When the fit is wrong, it just moves the pain somewhere less obvious.</p>
]]></content:encoded></item></channel></rss>