Loading the parity record
Fetching the measured run — the pinned upstream oracle, every symbol and every case.
Fetching the measured run — the pinned upstream oracle, every symbol and every case.
Parity / Express
Every number on this page was produced by running both implementations over the same cases: the real express package pinned at 4.21.2 answers first, and its answer is the expectation the Go port is held to. Nothing is a hand-written expectation, so a new upstream release re-scores the port on its own. See Express for the port's own documentation. Source: github.com/malcolmston/express.
Not a generic diagram: every node below names an artefact of this harness — the pinned package it installed, the runner files it started, the case files it streamed, and the counts it wrote out.
| Case group | Cases | Match | Mismatch | Group parity |
|---|---|---|---|---|
| routing-basic | 35 | 35 | 0 | 100.0% |
| response | 31 | 29 | 2 | 93.5% |
| routing-params | 25 | 25 | 0 | 100.0% |
| routing-mount | 16 | 16 | 0 | 100.0% |
| body | 15 | 15 | 0 | 100.0% |
| static | 15 | 15 | 0 | 100.0% |
| negotiation | 14 | 14 | 0 | 100.0% |
| routing-options | 12 | 12 | 0 | 100.0% |
| conditional | 9 | 9 | 0 | 100.0% |
| errors | 8 | 8 | 0 | 100.0% |
| routing-param | 4 | 4 | 0 | 100.0% |
Every exported symbol of the upstream package, and what the port offers for it. The upstream list is derived mechanically, never from a README: Enumerated with `Object.getOwnPropertyNames(require('express'))` on the installed package (31 names, including the JS `Function` internals `length`/`name`/`prototype` and the 17 deprecated Connect stubs, which throw on property access).. A symbol with no case is untested, never a match.
| Upstream symbol | Go symbol | Status | Cases | Note |
|---|---|---|---|---|
| express() | express.New | match | every fixture | |
| express.Router | express.NewRouter | match | mount-*, nested-*, router-middleware*, merge-params-* | |
| express.Route | express.Route | untested | — | app.route() chaining not exercised |
| express.application | *express.Application | match | every fixture | prototype object |
| express.request | *express.Request | match | every fixture | prototype object |
| express.response | *express.Response | match | every fixture | prototype object |
| express.json | express.JSON | differs | json-* | status on malformed body (400 vs 500); strict mode (upstream rejects non-object JSON); default {} vs nil when the content type does not match |
| express.urlencoded | express.URLEncoded | differs | urlencoded-* | Go yields url.Values ({"a":["1"]}) where upstream yields flat strings; invalid % escapes error in Go, are kept verbatim upstream |
| express.text | express.Text | untested | — | |
| express.raw | — | missing | — | no raw/[]byte body parser |
| express.static | express.Static | differs | static-* | no Cache-Control; no ETag; index.html 301-redirects to ./; broken under a mount prefix |
| express.query | built into Request.QueryValues | match | req-query* | the extended (qs) parser itself is not compared |
| express.length / .name / .prototype | — | untested | — | JavaScript Function internals, not express API |
| express.bodyParser | express.JSON/URLEncoded | untested | — | upstream getter throws by design (express 4 unbundled it); the Go port ships a same-named helper that this harness does not compare |
| express.compress | express.Compress | untested | — | upstream getter throws by design (express 4 unbundled it); the Go port ships a same-named helper that this harness does not compare |
| express.cookieParser | Request.Cookie | untested | — | upstream getter throws by design (express 4 unbundled it); the Go port ships a same-named helper that this harness does not compare |
| express.cookieSession | express.Session | untested | — | upstream getter throws by design (express 4 unbundled it); the Go port ships a same-named helper that this harness does not compare |
| express.csrf | middleware/csrf | untested | — | upstream getter throws by design (express 4 unbundled it); the Go port ships a same-named helper that this harness does not compare |
| express.directory | — | untested | — | upstream getter throws by design (express 4 unbundled it); the Go port ships a same-named helper that this harness does not compare |
| express.errorHandler | express.Recover | untested | — | upstream getter throws by design (express 4 unbundled it); the Go port ships a same-named helper that this harness does not compare |
| express.favicon | express.Favicon | untested | — | upstream getter throws by design (express 4 unbundled it); the Go port ships a same-named helper that this harness does not compare |
| express.limit | express.BodyLimit | untested | — | upstream getter throws by design (express 4 unbundled it); the Go port ships a same-named helper that this harness does not compare |
| express.logger | express.Logger | untested | — | upstream getter throws by design (express 4 unbundled it); the Go port ships a same-named helper that this harness does not compare |
| express.methodOverride | express.MethodOverride | untested | — | upstream getter throws by design (express 4 unbundled it); the Go port ships a same-named helper that this harness does not compare |
| express.multipart | express.Multipart | untested | — | upstream getter throws by design (express 4 unbundled it); the Go port ships a same-named helper that this harness does not compare |
| express.responseTime | express.ResponseTime | untested | — | upstream getter throws by design (express 4 unbundled it); the Go port ships a same-named helper that this harness does not compare |
| express.session | express.Session | untested | — | upstream getter throws by design (express 4 unbundled it); the Go port ships a same-named helper that this harness does not compare |
| express.staticCache | — | untested | — | upstream getter throws by design (express 4 unbundled it); the Go port ships a same-named helper that this harness does not compare |
| express.timeout | express.Timeout | untested | — | upstream getter throws by design (express 4 unbundled it); the Go port ships a same-named helper that this harness does not compare |
| express.vhost | — | untested | — | upstream getter throws by design (express 4 unbundled it); the Go port ships a same-named helper that this harness does not compare |
| app.get(path,...) | Router.Get | match | basic-*, param-*, mount-* (most cases) | |
| app.get(setting) | Application.GetSetting | untested | — | the reader half of the overloaded get |
| app.post | Router.Post | match | basic-post, basic-all-post, err-post-unmatched | |
| app.put | Router.Put | match | basic-put | |
| app.delete | Router.Delete | match | basic-delete, basic-all-delete | |
| app.del | — | missing | — | deprecated alias for delete |
| app.patch | Router.Patch | match | basic-patch | |
| app.head | Router.Head | differs | basic-head-explicit, basic-head-for-get*, etag-head, static-head | explicit HEAD routes work; **the Go port does not serve HEAD from a GET route** (404 instead of a bodyless 200) |
| app.options | Router.Options | match | basic-options-route, basic-options-auto | both answer an unrouted OPTIONS the same way after normalisation |
| app.all | Router.All | match | basic-all-* | |
| app.query | Router.Query | untested | — | the HTTP QUERY method |
| app.use | Router.Use | differs | mount-*, prefix-middleware*, err-*, static-mount-* | mounting works, but path-scoped middleware does not get the residual path, and an error before a mounted router does not skip it |
| app.param | Router.Param | match | param-cb-* | |
| app.route | Router.Route | untested | — | |
| app.set | Application.Set | differs | appset-strict-*, appset-case-* | strict routing and case sensitive routing are stored but never reach the root router in the Go port |
| app.enable | Application.Enable | untested | — | |
| app.disable | Application.Disable | untested | — | |
| app.enabled | Application.Enabled | untested | — | |
| app.disabled | Application.Disabled | untested | — | |
| app.engine | Application.Engine | untested | — | view engines are out of scope for this harness |
| app.render | Application.Render | untested | — | |
| app.listen | Application.Listen | untested | — | the runners use http.Server/ServeHTTP on a random port instead |
| app.path | — | missing | — | no mount-path accessor |
| app.handle | Application.ServeHTTP | match | every fixture | dispatch entry point |
| app.init / app.defaultConfiguration / app.lazyrouter | express.New | match | every fixture | internal construction |
| app.bind (length-style JS internals) | — | untested | — | JavaScript Function internals |
| app.acl | — | missing | — | rare HTTP verb from the methods package; the Go port exposes only GET/POST/PUT/DELETE/PATCH/HEAD/OPTIONS/QUERY/ALL |
| app.bind | — | missing | — | rare HTTP verb from the methods package; the Go port exposes only GET/POST/PUT/DELETE/PATCH/HEAD/OPTIONS/QUERY/ALL |
| app.checkout | — | missing | — | rare HTTP verb from the methods package; the Go port exposes only GET/POST/PUT/DELETE/PATCH/HEAD/OPTIONS/QUERY/ALL |
| app.connect | — | missing | — | rare HTTP verb from the methods package; the Go port exposes only GET/POST/PUT/DELETE/PATCH/HEAD/OPTIONS/QUERY/ALL |
| app.copy | — | missing | — | rare HTTP verb from the methods package; the Go port exposes only GET/POST/PUT/DELETE/PATCH/HEAD/OPTIONS/QUERY/ALL |
| app.link | — | missing | — | rare HTTP verb from the methods package; the Go port exposes only GET/POST/PUT/DELETE/PATCH/HEAD/OPTIONS/QUERY/ALL |
| app.lock | — | missing | — | rare HTTP verb from the methods package; the Go port exposes only GET/POST/PUT/DELETE/PATCH/HEAD/OPTIONS/QUERY/ALL |
| app.m-search | — | missing | — | rare HTTP verb from the methods package; the Go port exposes only GET/POST/PUT/DELETE/PATCH/HEAD/OPTIONS/QUERY/ALL |
| app.merge | — | missing | — | rare HTTP verb from the methods package; the Go port exposes only GET/POST/PUT/DELETE/PATCH/HEAD/OPTIONS/QUERY/ALL |
| app.mkactivity | — | missing | — | rare HTTP verb from the methods package; the Go port exposes only GET/POST/PUT/DELETE/PATCH/HEAD/OPTIONS/QUERY/ALL |
| app.mkcalendar | — | missing | — | rare HTTP verb from the methods package; the Go port exposes only GET/POST/PUT/DELETE/PATCH/HEAD/OPTIONS/QUERY/ALL |
| app.mkcol | — | missing | — | rare HTTP verb from the methods package; the Go port exposes only GET/POST/PUT/DELETE/PATCH/HEAD/OPTIONS/QUERY/ALL |
| app.move | — | missing | — | rare HTTP verb from the methods package; the Go port exposes only GET/POST/PUT/DELETE/PATCH/HEAD/OPTIONS/QUERY/ALL |
| app.notify | — | missing | — | rare HTTP verb from the methods package; the Go port exposes only GET/POST/PUT/DELETE/PATCH/HEAD/OPTIONS/QUERY/ALL |
| app.propfind | — | missing | — | rare HTTP verb from the methods package; the Go port exposes only GET/POST/PUT/DELETE/PATCH/HEAD/OPTIONS/QUERY/ALL |
| app.proppatch | — | missing | — | rare HTTP verb from the methods package; the Go port exposes only GET/POST/PUT/DELETE/PATCH/HEAD/OPTIONS/QUERY/ALL |
| app.purge | — | missing | — | rare HTTP verb from the methods package; the Go port exposes only GET/POST/PUT/DELETE/PATCH/HEAD/OPTIONS/QUERY/ALL |
| app.rebind | — | missing | — | rare HTTP verb from the methods package; the Go port exposes only GET/POST/PUT/DELETE/PATCH/HEAD/OPTIONS/QUERY/ALL |
| app.report | — | missing | — | rare HTTP verb from the methods package; the Go port exposes only GET/POST/PUT/DELETE/PATCH/HEAD/OPTIONS/QUERY/ALL |
| app.search | — | missing | — | rare HTTP verb from the methods package; the Go port exposes only GET/POST/PUT/DELETE/PATCH/HEAD/OPTIONS/QUERY/ALL |
| app.source | — | missing | — | rare HTTP verb from the methods package; the Go port exposes only GET/POST/PUT/DELETE/PATCH/HEAD/OPTIONS/QUERY/ALL |
| app.subscribe | — | missing | — | rare HTTP verb from the methods package; the Go port exposes only GET/POST/PUT/DELETE/PATCH/HEAD/OPTIONS/QUERY/ALL |
| app.trace | — | missing | — | rare HTTP verb from the methods package; the Go port exposes only GET/POST/PUT/DELETE/PATCH/HEAD/OPTIONS/QUERY/ALL |
| app.unbind | — | missing | — | rare HTTP verb from the methods package; the Go port exposes only GET/POST/PUT/DELETE/PATCH/HEAD/OPTIONS/QUERY/ALL |
| app.unlink | — | missing | — | rare HTTP verb from the methods package; the Go port exposes only GET/POST/PUT/DELETE/PATCH/HEAD/OPTIONS/QUERY/ALL |
| app.unlock | — | missing | — | rare HTTP verb from the methods package; the Go port exposes only GET/POST/PUT/DELETE/PATCH/HEAD/OPTIONS/QUERY/ALL |
| app.unsubscribe | — | missing | — | rare HTTP verb from the methods package; the Go port exposes only GET/POST/PUT/DELETE/PATCH/HEAD/OPTIONS/QUERY/ALL |
| req.accepts | Request.Accepts | differs | accepts-*, format-* | media-type selection agrees; see the offer-list findings below |
| req.acceptsCharsets | Request.AcceptsCharsets | differs | accepts-* | upstream falls back to an acceptable default where Go returns "" |
| req.acceptsEncodings | Request.AcceptsEncodings | differs | accepts-* | upstream treats identity as always acceptable and defaults to it with no header; Go does not |
| req.acceptsLanguages | Request.AcceptsLanguages | differs | accepts-json-first, accepts-no-headers | no language-range prefix matching in Go (en-GB does not match the offer en); no default when the header is absent |
| req.acceptsCharset / acceptsEncoding / acceptsLanguage | — | missing | — | deprecated singular aliases |
| req.fresh | Request.Fresh | differs | etag-revalidate-*, etag-star-validator | If-None-Match: * is not honoured; there is no framework ETag to revalidate against |
| req.stale | Request.Stale | untested | — | |
| req.get | Request.Get | match | req-info, etag-manual-* | |
| req.header | Request.Header | match | req-info | alias of get |
| req.hostname | Request.Hostname | match | req-info | presence only |
| req.host | — | missing | — | deprecated alias of hostname |
| req.ip | Request.IP | untested | — | loopback address is not a useful comparison |
| req.ips | — | missing | — | needs trust proxy, which the Go port lacks |
| req.is | Request.Is | untested | — | exercised indirectly by the body parsers |
| req.param(name) | — | missing | — | Go offers Params/Query separately, not the merged lookup |
| req.path | Request.Path | differs | req-info, mount-locations, prefix-middleware* | correct at the top level; inside a mounted router Go reports the full path, upstream the residual |
| req.protocol | Request.Protocol | match | req-info |
Every case the harness streamed to both runners, with the exact upstream symbol and Go symbol it exercised. A deliberate, documented difference is a deviation and is counted apart from a mismatch.
| Case | Group | Upstream symbol | Go symbol | Status | Note |
|---|---|---|---|---|---|
| json-object | body | express.json | express.JSON | match | |
| json-nested | body | express.json | express.JSON | match | |
| json-array | body | express.json | express.JSON | match | |
| json-empty-body | body | express.json | express.JSON | match | |
| json-charset | body | express.json | express.JSON | match | |
| json-malformed | body | express.json | express.JSON | match | malformed JSON must route to the error handler |
| json-scalar | body | express.json | express.JSON | match | |
| json-wrong-content-type | body | express.json | express.JSON | match | a non-JSON content type must be left unparsed |
| json-no-content-type | body | express.json | express.JSON | match | |
| urlencoded-simple | body | express.urlencoded | express.URLEncoded | match | |
| urlencoded-repeated | body | express.urlencoded | express.URLEncoded | match | |
| urlencoded-escaped | body | express.urlencoded | express.URLEncoded | match | |
| urlencoded-empty | body | express.urlencoded | express.URLEncoded | match | |
| urlencoded-flag-only | body | express.urlencoded | express.URLEncoded | match | |
| urlencoded-malformed-escape | body | express.urlencoded | express.URLEncoded | match | invalid percent escape |
| etag-first-response | conditional | app.set('etag') | — | match | express generates a weak ETag for res.send by default |
| etag-json-first | conditional | app.set('etag') | — | match | |
| etag-revalidate-304 | conditional | req.fresh | Request.Fresh | match | replay with If-None-Match from the previous response -> 304 |
| etag-revalidate-json-304 | conditional | req.fresh | Request.Fresh | match | |
| etag-stale-validator | conditional | req.fresh | Request.Fresh | match | a non-matching validator must yield the full 200 |
| etag-star-validator | conditional | req.fresh | Request.Fresh | match | |
| etag-manual-miss | conditional | res.set('ETag') | Response.ETag | match | |
| etag-manual-hit | conditional | res.status(304) | Response.NotModified | match | hand-rolled 304, independent of framework etag support |
| etag-head | conditional | app.set('etag') | — | match | |
| err-next | errors | app.use(err,req,res,next) | ErrorHandler | match | |
| err-throw | errors | app.use(err,req,res,next) | ErrorHandler | match | express catches a synchronous throw in a handler; the Go port needs express.Recover() |
| err-none | errors | app.get | Router.Get | match | |
| err-custom-404 | errors | app.use(fn) | Router.Use | match | |
| err-before-mount | errors | app.use(err,...) | ErrorHandler | match | |
| err-skips-subrouter | errors | app.use(path, mw, router) | Router.Use | match | the mount middleware errors, so the sub-router must be skipped and the app error handler must answer |
| err-router-local | errors | router.use(err,...) | ErrorHandler | match | a router-local error handler must win over the app-level one |
| err-post-unmatched | errors | app.use(fn) | Router.Use | match | |
| format-html | negotiation | res.format | Response.Format | match | |
| format-json | negotiation | res.format | Response.Format | match | |
| format-text | negotiation | res.format | Response.Format | match | |
| format-q-weighted | negotiation | res.format | Response.Format | match | |
| format-star | negotiation | res.format | Response.Format | match | single-entry map: */* takes the only offer |
| format-subtype-star | negotiation | res.format | Response.Format | match | |
| format-no-accept | negotiation | res.format | Response.Format | match | no Accept header at all |
| format-one-unacceptable | negotiation | res.format | Response.Format | match | single entry, nothing acceptable -> fallback vs 406 |
| format-406 | negotiation | res.format | Response.Format | match | no acceptable representation -> 406 |
| accepts-html-first | negotiation | req.accepts | Request.Accepts | match | |
| accepts-json-first | negotiation | req.accepts | Request.Accepts | match | |
| accepts-none-acceptable | negotiation | req.accepts | Request.Accepts | match | |
| accepts-no-headers | negotiation | req.accepts | Request.Accepts | match | |
| accepts-star | negotiation | req.accepts | Request.Accepts | match | |
| res-send-string | response | res.send | Response.Send | match | |
| res-send-object | response | res.send | Response.Send | match | |
| res-send-buffer | response | res.send | Response.Send | match | |
| res-json | response | res.json | Response.JSON | match | |
| res-json-key-order | response | res.json | Response.JSON | mismatch | JS preserves insertion order; Go map marshalling sorts keys |
| res-json-null | response | res.json | Response.JSON | match | |
| res-status | response | res.status | Response.Status | match | |
| res-send-status | response | res.sendStatus | Response.SendStatus | match | |
| res-send-status-418 | response | res.sendStatus | Response.SendStatus | match | |
| res-redirect-default | response | res.redirect | Response.Redirect | match | |
| res-redirect-301 | response | res.redirect | Response.Redirect | match | |
| res-type-json | response | res.type | Response.Type | match | |
| res-type-html | response | res.type | Response.Type | match | |
| res-type-full | response | res.type | Response.Type | match | |
| res-set | response | res.set | Response.Set | match | |
| res-append | response | res.append | Response.Append | match | |
| res-cookie-opts | response | res.cookie | Response.Cookie | match | |
| res-cookie-plain | response | res.cookie | Response.Cookie | match | |
| res-clear-cookie | response | res.clearCookie | Response.ClearCookie | match | |
| res-location | response | res.location | Response.Location | match | |
| res-links | response | res.links | Response.Links | match | |
| res-vary | response | res.vary | Response.Vary | match | |
| res-jsonp | response | res.jsonp | Response.JSONP | match | |
| res-jsonp-nocb | response | res.jsonp | Response.JSONP | match | |
| res-end-204 | response | res.end | Response.End | match | |
| req-cookie | response | req.cookies | Request.Cookie | deviation | express needs the cookie-parser middleware for req.cookies, so upstream reports undefined; the Go port reads cookies natively |
| req-info | response | req.path | Request.Path | match | |
| req-info-xhr | response | req.xhr | Request.Xhr | match | |
| req-query | response | req.query | Request.QueryValues | match | |
| req-query-empty | response | req.query | Request.QueryValues | match | |
| req-query-blank-value | response | req.query | Request.QueryValues | match | |
| default404-hit | routing-basic | app.get | Router.Get | match | |
| default404-miss | routing-basic | finalhandler | Application.ServeHTTP | match | the framework's own unmatched-route response |
| default404-miss-method | routing-basic | finalhandler | Application.ServeHTTP | match | |
| basic-root | routing-basic | app.get | Router.Get | match | |
| basic-a | routing-basic | app.get | Router.Get | match | |
| basic-ab | routing-basic | app.get | Router.Get | match | |
| basic-abc | routing-basic | app.get | Router.Get | match | |
| basic-404 | routing-basic | app.get | Router.Get | match | no route matches -> terminal 404 handler |
| basic-404-deep | routing-basic | app.get | Router.Get | match | |
| basic-post | routing-basic | app.post | Router.Post | match | |
| basic-put | routing-basic | app.put | Router.Put | match | |
| basic-delete | routing-basic | app.delete | Router.Delete | match | |
| basic-patch | routing-basic | app.patch | Router.Patch | match | |
| basic-options-route | routing-basic | app.options | Router.Options | match | |
| basic-options-auto | routing-basic | app.options | Router.Options | match | express auto-answers OPTIONS with an Allow header |
| basic-method-not-allowed | routing-basic | app.get | Router.Get | match | wrong method on an existing path -> 404, not 405 |
| basic-head-explicit | routing-basic | app.head | Router.Head | match | |
| basic-head-for-get | routing-basic | app.head | Router.Head | match | express serves HEAD from a GET route with an empty body |
| basic-head-for-get-root | routing-basic | app.head | Router.Head | match | |
| basic-all-get | routing-basic | app.all | Router.All | match | |
| basic-all-post | routing-basic | app.all | Router.All | match | |
| basic-all-delete | routing-basic | app.all | Router.All | match | |
| basic-dup-first-wins | routing-basic | app.get | Router.Get | match | two identical routes: the first registered wins |
A case can show the port is less safe than the library it ports. Those findings are written into security.json and filed as draft advisories, never as public issues with a working repro.
| Finding | Severity | Affected | Cases | Summary |
|---|---|---|---|---|
| GHSA-2c3q-x282-q3r4 | high | <= 0.4.0 | default-404-xss | Reflected XSS in the default 404 handler (request path echoed into unescaped text/html) |
| GHSA-38wj-v3mf-hf7p | medium | <= 0.4.0 | encoded-slash-prefix-bypass | Percent-encoded slashes decoded before routing, enabling path-prefix authorisation bypass |
Express's repo also ports 28 packages that each have their own upstream — for example a qs port inside the express repo is measured against npm qs, not against express. Each has a separate harness under parity/express/nested/, its own pinned oracle, and its own score; none of them changes the Express score above. Together they add 4,277 cases and 446 inventoried symbols.
| Nested port | Its own upstream | Go module | Cases | Mismatch | Deviations | Symbols | Parity |
|---|---|---|---|---|---|---|---|
| express/accepts | accepts@1.3.8 | github.com/malcolmston/express v0.4.0 => ../../../../express | 117 | 0 | 0 | 16 | 100.0% |
| express/bytes | bytes@3.1.2 | github.com/malcolmston/express@v0.4.0 | 230 | 0 | 12 | 21 | 100.0% |
| express/camelcase | camelcase@9.0.0 | github.com/malcolmston/express v0.4.0 => ../../../../express | 260 | 0 | 0 | 15 | 100.0% |
| express/contenttype | content-type@1.0.5 | github.com/malcolmston/express v0.4.0 => ../../../../express | 76 | 0 | 0 | 4 | 100.0% |
| express/cookiesignature | cookie-signature@1.2.2 | github.com/malcolmston/express@v0.4.0 | 54 | 0 | 0 | 2 | 100.0% |
| express/deburr | lodash@4.17.21 | github.com/malcolmston/express v0.4.0 => ../../../../express | 81 | 0 | 0 | 7 | 100.0% |
| express/escapehtml | escape-html@1.0.3 | github.com/malcolmston/express v0.4.0 => ../../../../express | 36 | 0 | 0 | 1 | 100.0% |
| express/escaperegexp | escape-string-regexp@5.0.0 | github.com/malcolmston/express v0.4.0 => ../../../../express | 61 | 0 | 0 | 1 | 100.0% |
| express/filesize | filesize@11.0.22 | github.com/malcolmston/express v0.4.0 => ../../../../express | 188 | 0 | 0 | 24 | 100.0% |
| express/htmlentities | html-entities@2.6.0 | github.com/malcolmston/express v0.4.0 => ../../../../express | 113 | 0 | 3 | 20 | 100.0% |
| express/jsonwebtoken | jsonwebtoken@9.0.3 | github.com/malcolmston/express@v0.4.0 | 129 | 0 | 9 | 37 | 100.0% |
| express/jwtdecode | jwt-decode@4.0.0 | github.com/malcolmston/express@v0.4.0 | 49 | 0 | 4 | 4 | 100.0% |
| express/kebabcase | change-case@5.4.4 | github.com/malcolmston/express v0.4.0 => ../../../../express | 102 | 0 | 0 | 13 | 100.0% |
| express/keygrip | keygrip@1.1.0 | github.com/malcolmston/express@v0.4.0 | 65 | 0 | 2 | 10 | 100.0% |
| express/mimetypes | mime-types@2.1.35 | github.com/malcolmston/express v0.4.0 => ../../../../express | 188 | 0 | 0 | 7 | 100.0% |
| express/ms | ms@4.0.0-nightly.202508271359 | github.com/malcolmston/express@v0.4.0 | 180 | 0 | 2 | 7 | 100.0% |
| express/nanoid | nanoid@6.0.1 | github.com/malcolmston/express v0.4.0 => ../../../../express | 126 | 0 | 3 | 10 | 100.0% |
| express/negotiator | negotiator@0.6.3 | github.com/malcolmston/express v0.4.0 => ../../../../express | 142 | 0 | 0 | 15 | 100.0% |
| express/otpauth | otpauth@9.5.1 | github.com/malcolmston/express@v0.4.0 | 164 | 0 | 6 | 22 | 100.0% |
| express/pluralize | pluralize@8.0.0 | github.com/malcolmston/express v0.4.0 => ../../../../express | 464 | 0 | 14 | 14 | 100.0% |
| express/prettybytes | pretty-bytes@7.1.1 | github.com/malcolmston/express v0.4.0 => ../../../../express | 190 | 0 | 3 | 17 | 100.0% |
| express/qs | qs@6.15.3 | github.com/malcolmston/express@v0.4.0 | 271 | 0 | 3 | 46 | 100.0% |
| express/sanitizehtml | sanitize-html@2.17.6 | github.com/malcolmston/express v0.4.0 => ../../../../express | 233 | 0 | 10 | 33 | 100.0% |
| express/semver | semver@7.8.5 | github.com/malcolmston/express@v0.4.0 | 320 | 0 | 7 | 68 | 100.0% |
| express/slugify | slugify@1.6.9 | github.com/malcolmston/express v0.4.0 => ../../../../express | 75 | 0 | 5 | 13 | 100.0% |
| express/statuses | statuses@2.0.1 | github.com/malcolmston/express v0.4.0 => ../../../../express | 142 | 0 | 1 | 7 | 100.0% |
| express/striptags | striptags@3.2.0 | github.com/malcolmston/express v0.4.0 => ../../../../express | 116 | 0 | 7 | 6 | 100.0% |
| express/typeis | type-is@1.6.18 | github.com/malcolmston/express v0.4.0 => ../../../../express | 105 | 0 | 0 | 6 | 100.0% |