MuPDF.js latest updates

Jamie Lemon·June 11, 2024

MuPDFMuPDF.jsRelease
MuPDF.js latest updates

It’s been a year since we published our first version of MuPDF.js to NPM and a lot has happened since then. Let’s check in on what we’ve achieved!

TypeScript support

TypeScript is a superset of JavaScript that adds static typing and other features to the language. It has gained significant popularity among developers due to its many benefits. Here is what it brings:

1. Static Typing

  • Error Detection: TypeScript's static type system helps catch errors during development rather than at runtime, reducing the chances of bugs in the production environment.
  • IntelliSense: With types, editors and IDEs can provide better autocompletion, navigation, and refactoring capabilities, improving developer productivity.

2. Improved Code Quality

  • Type Inference: TypeScript can infer types even if you don't explicitly declare them, leading to cleaner and more maintainable code.
  • Strict Null Checks: It helps prevent null or undefined errors by enforcing checks, making your code more robust.

3. Enhanced IDE Support

  • Better Tooling: TypeScript's integration with popular editors like Visual Studio Code offers enhanced features such as intelligent code completion, code navigation, and refactoring tools.
  • Refactoring: TypeScript makes it easier to refactor code safely by providing better support for code modifications and detecting potential issues early.

4. Compatibility with JavaScript

  • JavaScript Ecosystem: TypeScript works well with all JavaScript libraries and frameworks, ensuring that you can use it without losing compatibility with the vast JavaScript ecosystem.

5. Improved Maintainability

  • Self-Documenting Code: With types, the codebase becomes more readable and self-documenting, making it easier for new developers to understand and maintain the code.
  • Refactoring and Reusability: Type definitions make it easier to refactor and reuse code, as dependencies and relationships between different parts of the code are clearer.

6. Scalability

  • Large-Scale Projects: TypeScript is particularly beneficial for large-scale applications where maintaining and understanding a growing codebase can become challenging. Its type system helps manage complexity and ensures code correctness as the project scales.
  • Modularization: TypeScript supports ES6 modules, which helps in organizing code better, especially in large applications.

To put it simply, TypeScript support is a natural choice for web developers and now MuPDF.js can leverage this.

Improving the capabilities of the library

A year ago much of the core MuPDF API was not being available as you might expect. We have worked hard on bringing more of the core features of MuPDF into the library to provide a more complete feature set, including:

Out of the box examples

We’ve improved our GitHub with an examples folder. This includes:

Simple viewers

Now contains 2 “vanilla” JavaScript examples to help get you started. Both are simple - one uses web workers and has a little bit of UI options, the other is just one file and will render all pages of PDF to the web browser for viewing.

Client / server example

A Node backend and a React front-end which talks to it. Designed for a sample RESTful solution this is a good place to get started if you need to build an application which relies on a Node.js server side solution.

Formal Testing

We’ve added formal test scripts in TypeScript to make maintenance more robust. For our in-house development this means we can better understand our workflow and avoid making any breaking changes to the library as we develop.

import * as fs from 'fs';
import * as mupdf from 'mupdf';
import path from 'path';
import { afterAll, beforeAll, describe, expect, it } from 'vitest';

const scriptdir = path.resolve(__dirname);
const filename = path.join(scriptdir, "resources", "001003ED.pdf");
const metafile = path.join(scriptdir, "resources", "metadata.txt");

describe('mupdfjs metadata tests', () => {
    let document: mupdf.PDFDocument;

  beforeAll(async () => {
    const data = fs.readFileSync(filename);
    document = await mupdf.Document.openDocument(data, 'application/pdf') as mupdf.PDFDocument;
  });

  afterAll(() => {
    document.destroy();
  });

  it('should match metadata with expected result', async () => {
    const metadata = {
      format: document.getMetaData("format"),
      title: document.getMetaData("info:Title"),
      author: document.getMetaData("info:Author"),
      subject: document.getMetaData("info:Subject"),
      keywords: document.getMetaData("info:Keywords"),
      creator: document.getMetaData("info:Creator"),
      producer: document.getMetaData("info:Producer"),
      creationDate: document.getMetaData("info:CreationDate"),
      modDate: document.getMetaData("info:ModDate"),
      trapped: document.getMetaData("info:Trapped"),
      encryption: document.getMetaData("info:Encryption")
    };

    const expectedMetadata = JSON.parse(fs.readFileSync(metafile, 'utf8'));
    // Convert undefined to an empty string
    function normalize(obj: any) {
        return JSON.parse(JSON.stringify(obj, (key, value) => value === undefined ? '' : value));
    }
    expect(normalize(metadata)).toEqual(normalize(expectedMetadata));
  });
})

Sample Test Script


Improved Documentation

It goes without saying that for the best Developer Experience we need great documentation. We’ve been continually developing the documentation over on Read The Docs to bring the API to you - we appreciate we can’t let your IDE do all the guesswork here 🙂.

Conclusion

With more and more people picking up the library and getting involved we hope by focussing on these 5 areas that MuPDF.js will continue to bring value.

  • TypeScript Support
  • Feature Updates
  • More Examples
  • Formal Testing
  • Improved Documentation

Check out MuPDF.js on Github and/or install MuPDF from NPM to try things out!