Remove lodash, replace with escape-html

f72d8586f14c8215c0c0c01fc254ddab9e35aeb6

Tucker McKnight <tucker@pangolin.lan> | Mon Feb 02 2026

Remove lodash, replace with escape-html

escape-html is a comparatively tiny library. All I was using of
lodash was just the HTML escape function.

Incidentally, I fixed a bug that was happening that would sometimes
cause escaped HTML characters to show up. This was because a
<mark> was being inserted for the red/green diff highlighting, and
it was being inserted in between the characters for an escape character.
E.g. something like &<mark>lt; which would then not get rendered as
a < because it doesn't actually say &lt;. Doing the diff first, with
the HTML characters in the string, and *then* escaping them afterwards
fixes this.
js_templates/feed.ts:1
Before
1
import _ from 'lodash'
After
1
js_templates/feed.ts:26
Before
26
27
28
29
          m('name', `${_.escape(currentRepo.name)} contributors`)
            m('title', _.escape(commit.commit.message.split('\n')[0])),
            m('author', m('name', _.escape(commit.commit.author))),
            m('content', {type: "text"}, _.escape(commit.commit.message)),
After
26
27
28
29
          m('name', `${currentRepo.name} contributors`)
            m('title', commit.commit.message.split('\n')[0]),
            m('author', m('name', commit.commit.author)),
            m('content', {type: "text"}, commit.commit.message),
package-lock.json:12
Before
12
        "lodash": "^4.17.21",
After
12
        "escape-html": "^1.0.3",
package-lock.json:1080
Before
1080
After
1080
    "node_modules/escape-html": {
      "version": "1.0.3",
      "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
      "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
    },
package-lock.json:1282
Before
1282
1283
1284
1285
1286
    "node_modules/lodash": {
      "version": "4.17.23",
      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz",
      "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w=="
    },
After
1282
1283
1284
1285
1286
package.json:29
Before
29
    "lodash": "^4.17.21",
After
29
    "escape-html": "^1.0.3",
src/helpers.ts:1
Before
1
import _ from 'lodash'
After
1
import escape from 'escape-html'
src/helpers.ts:37
Before
37
38
39
40
41
42
      lastHunkBefore = _.escape(lastHunkBefore)
      lastHunkAfter = _.escape(lastHunkAfter)
          beforeText = beforeText + obj.value
          afterText = afterText + obj.value
          afterText = afterText + "<mark>" + obj.value + "</mark>"
          beforeText = beforeText + "<mark>" + obj.value + "</mark>"
After
37
38
39
40
41
42
          beforeText = beforeText + escape(obj.value)
          afterText = afterText + escape(obj.value)
          afterText = afterText + "<mark>" + escape(obj.value) + "</mark>"
          beforeText = beforeText + "<mark>" + escape(obj.value) + "</mark>"
wiki/index.md:12
Before
12
13
14
15
16
17
18
- [ ] get rid of lodash
  - [Project page](./projects/node-18.md.html)
  - also use globs npm module instead of built-in node version, built-in requires
    node 20+.
  - add a Dockerfile for node 18, which is the lowest 11ty supports, and see if
    this is useable on that.
  - lodash is one of the larger (largest?) dependencies right now. With mithril auto-escaping strings, it might not be necessary anymore. Look into which things actually need to be escaped (e.g. any user-input from commit messages) and see if we can just rely on mithril to escape those
After
12
13
14
15
16
17
18
wiki/index.md:68
Before
68
After
68
- [x] get rid of lodash
  - [Project page](./projects/node-18.md.html)
  - also use globs npm module instead of built-in node version, built-in requires
    node 20+.
  - add a Dockerfile for node 18, which is the lowest 11ty supports, and see if
    this is useable on that.
  - lodash is one of the larger (largest?) dependencies right now. With mithril auto-escaping strings, it might not be necessary anymore. Look into which things actually need to be escaped (e.g. any user-input from commit messages) and see if we can just rely on mithril to escape those
wiki/projects/node-18.md:1
Before
1
After
1
\#completed
wiki/projects/node-18.md:17
Before
17
After
17

## Feb 1, 2026

- Replaced webpack with rollup
- Replaced lodash with escape-html
- Only a few functions needed to be changed to to work with node 18