DEV Community

Cover image for Why TypeScript’s DOM Library Generator Is Moving from JSON to KDL
Adam Naji
Adam Naji

Posted on • Originally published at zyvop.com

Why TypeScript’s DOM Library Generator Is Moving from JSON to KDL

What is the TypeScript DOM Library Generator

If you've ever written TypeScript for a browser project, you've likely used APIs like:

\n\n


window.localStorage;

fetch("https://example.com");
\n```

\n\n

These types don't just appear out of nowhere. They come from a generated file called `lib.dom.d.ts`.

The TypeScript DOM generator is the tool responsible for creating that file.

Instead of writing thousands of browser API definitions by hand, it pulls information from web standards and generates TypeScript declarations.

In simpler terms:

\n\n

```plaintext\nWeb standards
      ↓
TypeScript DOM lib generator
      ↓
lib.dom.d.ts
      ↓
TypeScript IntelliSense and type checking
\n```

\n\n

This tool serves as the bridge between the browser platform and the TypeScript developer experience.

## Where do we use JSON in that flow?

The project has strict guidelines for a browser API to be added to the project; it must be supported by at least two main browser engines, so that you can make your code as compatible as possible with all modern browsers, without having to worry about compatibility.

So we use data from [MDN Browser Compact Data](https://github.com/mdn/browser-compat-data) to make sure every api is supported; sometimes we can't detect the APIs correctly from the repo or the documented api is incorrect. Or, in the worst cases, the web standards return an api that no browser has implemented yet like `pinComplexityPolicy` which has no implementor.

So they decided to create 3 new JSON files: removedTypes, overrideTypes, and addedTypes.

But if you are a contributor to the repo, you will notice that they use `.jsonc` not a regular JSON file, which is the same as JSON with an addition to comments.

## Why is TypeScript DOM Library Generator migrating to kdl?

If you know anything about web development, it is a crazy world with a lot of new APIs that get added every day, so the `.jsonc` files got massive; one file reached over 3000 lines alone.

Also, the format you write the overrides in is very brutal, and not a lot of people can understand it.

Try to understand this snippet of a real thing in the repo:

\n\n

```json\n            "LockManager": {
                "methods": {
                    "method": {
                        "request": {
                            "typeParameters": {
                                "name": "T"
                            },
                            "signature": {
                                "0": {
                                    "typeParameters": [
                                        {
                                            "name": "T"
                                        }
                                    ],
                                    "param": [
                                        {
                                            "name": "callback",
                                            "overrideType": "LockGrantedCallback<T>"
                                        }
                                    ],
                                    "overrideType": "Promise<Awaited<T>>"
                                },
                                "1": {
                                    "typeParameters": [
                                        {
                                            "name": "T"
                                        }
                                    ],
                                    "param": [
                                        {
                                            "name": "callback",
                                            "overrideType": "LockGrantedCallback<T>"
                                        }
                                    ],
                                    "overrideType": "Promise<Awaited<T>>"
                                }
                            }
                        }
                    }
                }
            },
\n```

\n\n

If you are wondering what the output of the above is, this is the output

\n\n

```typescript\n/**
 * The **`LockManager`** interface of the Web Locks API provides methods for requesting a new Lock object and querying for an existing Lock object. To get an instance of LockManager, call navigator.locks.
 * Available only in secure contexts.
 *
 * [MDN Reference](https://developer.mozilla.org/docs/Web/API/LockManager)
 */
interface LockManager {
    // rest of the code
    /**
     * The **`request()`** method of the LockManager interface requests a Lock object with parameters specifying its name and characteristics. The requested Lock is passed to a callback, while the function itself returns a Promise that resolves (or rejects) with the result of the callback after the lock is released, or rejects if the request is aborted.
     *
     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/LockManager/request)
     */
    request<T>(name: string, callback: LockGrantedCallback<T>): Promise<Awaited<T>>;
    request<T>(name: string, options: LockOptions, callback: LockGrantedCallback<T>): Promise<Awaited<T>>;
}\n```

\n\n

## What is KDL?

KDL is a small, pleasant document language with XML-like node semantics that looks like you are invoking a bunch of CLI commands. It is meant to be used both as a serialization format and a configuration language, much like JSON, YAML, or XML.

## My part in the JSON to KDL migration

I saw that [Kagami Sascha Rosylight (saschanaz)](https://github.com/saschanaz), who works at Mozilla and is the core maintainer of that repository, posted saying that the JSONC file is massive and we should migrate to KDL in [#2053](https://github.com/microsoft/TypeScript-DOM-lib-generator/issues/2053). I took the initiative and started working on it, and this is the new way to write overrides in the Microsoft DOM Library project.

\n\n

```typescript\n// Manually moved from Document
// See https://github.com/w3c/csswg-drafts/issues/5886 and https://github.com/w3c/csswg-drafts/issues/556
interface-mixin DocumentOrShadowRoot {
  method elementFromPoint {
    type Element nullable=#true
    param x type=long
    param y type=long
  }
  method elementsFromPoint {
    type sequence {
      type Element
    }
    param x type=long
    param y type=long
  }
}
\n```

\n\n

It is very similar to webidl and simple to read.

## Difficulties migrating

It is not very easy to migrate from a JSON file to small KDL files, so I spent most of my contributions on the KDL parser to compile the KDL into JSON that we can later use to compile into TypeScript. Currently, the file is almost 600 lines long, and there are still a lot of things missing that need to be added to it.

What do you think: would you use KDL or keep using massive JSON files?

---

*Originally published on [ZyVOP](https://zyvop.com/why-typescript-s-dom-library-generator-is-moving-from-json-to-kdl-g52v6)*

💡 For more articles like this, [subscribe to the ZyVOP newsletter](https://zyvop.com/newsletter)!
Enter fullscreen mode Exit fullscreen mode

Top comments (0)