- 14 minutes read

My PDF viewer crossed the ten thousand downloads per week mark! What started as a little pet project has become tremendously popular. So let's talk about it. I've also done a little research, and my PDF viewer isn't the only one. I've found several alternatives. I will present these alternatives, too, and I will give you a few hints on when to use which.

The "making of" story

PDF files are popular. Angular is popular, too. So there's little doubt there's a PDF viewer for Angular. Or so I thought roughly two years ago. My customer then asked me to display PDF files in an Angular application. To my surprise, my research showed few results. Steffen Schäfer had a little tutorial on how to integrate pdf.js into your web application. There also was a great PDF viewer for AngularJS 1.x. Apart from the "1.x" bit, it was exactly what I needed. But I wasn't into software archeology. I needed something for contemporary Angular. We found several simple solutions, such as the ng2-pdf-viewer project of Vadym Yatsyuk. Don't get me wrong: it's a great project. Highly recommended! The only disadvantage is it's just the core viewer without additional UI. We wanted the complete PDF viewer, batteries included. My customer needs all the extra features such as search, zoom, rotating, printing, and so on. Just displaying the file wasn't enough.

pdf.js to the rescue

 screenshot of the showcase of pdf.jsScreenshot of the showcase of pdf.js published under an Apache V2 licenseHowever, we already knew it's possible to integrate a PDF viewer into a web application. Have a look at the showcase of the pdf.js project. It's a website, and the source code is publicly available on GitHub under a friendly Apache V2 license. The only challenge is that this project hasn't been written with web applications in mind. It's the native PDF viewer of Firefox, so it uses a lot of global variables, global CSS, and all the other shortcuts you take when you know there's no third-party code. However, your application is precisely that, so the challenge was to find a way to make pdf.js coexist peacefully with your application. Not to mention embedding it into the Angular life cycle.

To cut a long story short, I integrated Mozilla's PDF viewer into an Angular ecosystem. I also decided to make it an open-source project. That, in turn, had several consequences. I had to spend a lot of precious leisure time on the project. It's been the most challenging project I've ever conducted in my professional life. But it also meant I could add all the features I wanted. Third, thousands of developers and countless end users thoroughly test the PDF viewer.

Because that's the surprise: as soon as I published the library on npm, people started to use it. I didn't have to advertise it. Before long, I saw a hundred downloads each week.

As you can imagine, the early adopter started reporting bugs and ideas to improve the library on my bug tracker. During the last two years, I made it a habit to solve these bugs, help developers, and answer their questions. Every couple of days, I publish a new version. That's been a lot of work, but it's also been a lot of fun. If you're thinking about doing open source, beware: it's addictive!

Which other options do you have?

A couple of months later, I learned that another guy called CodeHippy started a similar project roughly at the same time as I did. That's great because CodeHippy uses a slightly different approach. Now Angular developers can choose between several options:

  •  screenshot of ngx-extended-pdf-viewerScreenshot of ngx-extended-pdf-viewerMy pet library, ngx-extended-pdf-viewer, integrates Mozilla's PDF viewer into your Angular application as tightly as possible. It offers two-way binding for many attributes, such as [(page)], [(zoom)], [(rotate)] and even [(src)]. Your application can react when the user scrolls through the document, changes the zoom, rotates it, or even opens a new document. My pet library is also SEO-friendly. Google sees both your Angular application and the PDF file it's displaying. It also has the largest showcase among the open-source options.
  • screenshot of the showcase of ng2-pdfjs-viewerScreenshot of ng2-pdfjs-viewerThe library written by CodeHippy, ng2-pdfjs-viewer, uses a different approach. Truth to tell, it's brilliant. CodeHippy embeds Mozilla's library in an iFrame. We all know that iFrames are evil. Only… they aren't. Not always, that is. In this particular case, iFrames are the tool of choice. They are the perfect way to isolate the PDF viewer from your application. So CodeHippy didn't have to fight all the global CSS rules. Nice!
  • And then there's the good old library written by Vadim Yatsyuk. It's the pure PDF viewer without bells and whistles. It's been around since the Summer of 2016, so it's both the most mature and popular option. Eight hundred stars on GitHub and 700+ commits talk of a lot of trust and experience. Not to mention 45.000 downloads per week. The only disadvantage is you only get the core PDF viewer. Everything that makes viewer PDF files fun — the menu, the toolbar, zooming, rotating, printing — is your job. The library offers a decent API to implement these features, but it doesn't deliver them out of the box. On the plus side, this approach gives you maximum flexibility. In many cases, it's exactly what you need. Bells and whistles add a lot to the atmosphere, but they distract your user from the content.
  • During my research, ej2-angular-pdfviewer caught my eye. At first glance, it looks like an open-source project. It's available on npm, the source code is published on GitHub, and it looks decent enough. I shy away from it for precisely one reason. ej2-angular-pdfviewer has been published under a license, that's a bit peculiar. You're well off if you pay for it. Under certain circumstances, you can also use it for free, but that requires you to meet many conditions. I'm not a lawyer, so I prefer to use products with a well-known license. As for the product itself, it seems to be a bit limited with features, but on the plus side, it seems to be well-thought and has a great showcase and manual.
  • This article written by PDFTron is much better news. They also want to sell you their product. But before that, they show you how simple it is to use Vadim's library as a basis to add a decent UI to it. I have to admit this looks like a valid alternative to both ngx-extended-pdf-viewer and ng2-pdfjs-viewer. If you're interested in a do-it-yourself solution, have a look at https://github.com/PDFTron/ng5-pdf-viewer-ui.
  • If you don't need a lot of features, you can also use the native PDF viewer of your browser. According to w3docs, the recommended way is using an iFrame. <embed> and <object> went out of fashion.

Benefits of commercial solutions

Talking about PDFTron: what are the advantages commercial solutions offer to you?

I don't see many advantages if your goal is to display PDF files. Chances are the commercial PDF viewer has a feature the open-source viewer doesn't offer. But in general, I'm convinced ngx-extended-pdf-viewer is the pack's leader, feature-wise, with CodeHippy's ng2-pdfjs-viewer being a close second.

However, things look different if you want to modify a PDF file. None of the open-source PDF viewers offers options for that. You'll love the commercial solutions if you need to add comments or graphics, mark texts, add a signature, or work with forms. Have a look at the PDFTron demo and this Syncfusion demo to see what I'm talking about.

Update September 27, 2020:

Starting with pdf.js 2.6, limited form support has landed in open-source country.

Update December 28, 2022:

The new version ngx-extended-pdf-viewer 2.16 also offers to add texts and free-hand sketches to the PDF file. It's already available as an alpha version, and the final release is going to land in January 2023.

Getting started with ngx-extended-pdf-viewer

Have you come here for the source code? All right, let's make our feet wet.

It takes merely five minutes to get started. Even faster, depending on your internet connection. In a nutshell, all you have to do is run an Angular schematic:

ng add ngx-extended-pdf-viewer

This command generates an example component if you accept all the defaults. You only have to add it to an HTML template yourself. If you need more support, have a look at the getting started page of the showcase. Over there, you'll also learn how to get the PDF viewer up and running with Ionic, JHipster, and Angular 5.

You're rewarded with a PDF viewer that resembles the native viewer of Firefox. There are subtle differences because the Mozilla teams asked me to make my PDF viewer look different. So I replaced most of the standard icons with Material Design icons. By default, the PDF viewer currently looks like so:

Dachstein mountain displayed by ngx-extended-pdf-viewer. Picture shot by Stephan Rauh.

Adding value to Mozilla's PDF viewer

My project's original goal was to integrate Firefox's PDF viewer into your application without modifying it much. By now, ngx-extended-pdf-viewer has evolved beyond that. When it seems appropriate (and a user demands it), I'm ready to improve the original PDF viewer. I'll show you two examples.

  • I've taken the liberty to improve the find dialog. The screenshot shows you can find words ignoring diacritics and multiple words or phrases simultaneously. Each phrase is displayed with a different color: Screenshot of the PDF viewer featuring the enhanced find options.
  • Many users want to customize the PDF viewer. Since version 2.0, you can do that to a vast degree. I'm sure I'll add even more options in the future. You have full control over the toolbar, the find bar, and the secondary menu. For example, you can implement alternative zoom options: ngx-extended-pdf-viewer with custom zoom radio buttons.

Attributes, events, and two-way binding

That's just the beginning. ngx-extended-pdf-viewer offers roughly sixty attributes. That is one of the key differences to ng2-pdf-viewer, which provides 19 attributes, and ng2-pdfjs-viewer, offering 35 attributes, give or take a few. The exact numbers are not important. It's more important to notice the relative numbers:

  • Vadym has published a rock-solid core library. It's just the core PDF file. So it doesn't need all these attributes.
  • CodeHippie has published a full-blown PDF viewer. Their distinguishing design decision is to run it in a separate namespace. Technically, that's an iFrame. That, in turn, means they can't offer the full range of options. Or maybe they can, but it doesn't come for free.
  • My library is the most ambitious one. It offers a close integration of the PDF viewer to your application. At the same time, it allows you to customize the PDF viewer to a wide range. Call me a lunatic because that's what I'm doing. I'm trying to achieve two impossible goals at the same time. So far, I'm getting away with it. I'm careful — I don't agree with every feature request! — but my library may be going to be punished by a breaking change in the future. The challenge is to offer you as much flexibility as possible without making it impossible to update to a future version of pdf.js. That isn't easy because I'm not part of the pdf.js team. But then, that's the art of every framework designer: trying to anticipate potentially damaging modifications.

That's more or less the decision matrix I've promised you. Let's make it a little more concise:

  • Do you need to display PDF files? Choose ng2-pdf-viewer. It's just the core library, but when that's all you need, that's the way to go.
  • Do you need to display multiple PDF files simultaneously? Opt for the library published by CodeHippie, ng2-pdfjs-viewer.
  • Do you need two-way interaction between the PDF viewer and your application? Such as reacting to rotation or zoom changes? Have a look at ngx-extended-pdf-viewer.
  • Do you want to customize the menu, the toolbar, or anything else? Then my pet library is your friend.
  • Do you need a PDF viewer that goes beyond the standard features? Such as additional options to find texts? Check out my library. Or open a feature request if it doesn't meet your requirements yet.

What's in store for you?

In the end, let me tell you about my plans. First of all, the Mozilla pdf.js team never sleeps. So it's high time to update to the next version of pdf.js.

Second, solving the new bugs you're reporting to me is always challenging, and keeping the code quality bar high is always top of my list.

But I'm optimistic I can finally move on. My short-term goal is to implement Angular schematics. Adding ngx-extended-pdf-viewer should be a one-liner.

Update December 28, 2022:

In the meantime, the schematics has landed. You've already seen it in action above.

And then there's my long-term goal. Mind you, Angular is all good and well, and I love Angular. Nonetheless, I can't deny that the rest of the JavaScript universe is much greater than the Angular world. So I'd like to convert the PDF viewer to a web component. That, in turn, allows it to be used by Vue.js programmers, React.js developers, and every other JavaScript aficionado.

Wrapping it up

Being the developer of ngx-extended-pdf-viewer, I'm biased. I want you to talk into using my library. It's tremendously popular, I know many companies use it for their business, so I'm pretty sure it's a good choice.

But I also want you to choose a suitable library for your project. It might be my project, but it's not the perfect solution for every problem. That's why I've also shown you several alternatives.

If you're an Angular programmer, two other simple open-source libraries allow you to add a PDF viewer to your application: ng2-pdf-viewer and ng2-pdfjs-viewer. Each of these libraries has its advantages. ng2-pdf-viewer is a rock-solid viewer if you're interested in displaying the content and nothing else. ng2-pdfjs-viewer is excellent if you want to show multiple PDF files on the same page. ngx-extended-pdf-viewer offers the closest integration between the PDF viewer and your application, plus a wide range of options and customizations.

Update December 28, 2022:

In the meantime, I've figured out how to display multiple PDF files using ngx-extended-pdf-viewer. It's almost a hack, but it works well, as shown on the showcase.

There are also numerous professional solutions at hand. This article presents two of them. In general, there's nothing wrong with using a professional solution. Quite the contrary, your money allows someone else to make a living. That's just great. Plus, professional solutions can offer features no open-source library will offer, such as adding annotations and comments to a PDF file. Just make sure you've read and understood the license. You can't assume you can legally use a library just because it's publicly available on npm or GitHub. I'm not a lawyer, but when I started investigating the topic, I learned that the default GitHub license only allows you to view the file with a GitHub tool. That doesn't even include downloading, forking, or editing the project.

If you're the adventurous one, you've got even more options. Head over to my 2017 article if you're curious. For example, if you don't need to support Internet Explorer, you can also use the native PDF viewer of your browser. You'll lose control and features, but it's a lightweight solution with a small memory footprint.

Be that as it may, ngx-extended-pdf-viewer is an incredible success story. I knew it'd hit a nerve. But I never dared hope it'd attract that much demand, and I feel deeply honored by that. Mind you: 10.000 downloads per week amounts to 10.000 displays of trust.


Comments