ultimate-express 1.2.16 → 1.2.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,315 +1,315 @@
1
- # µExpress / Ultimate Express
2
-
3
- The *Ultimate* Express. Fastest http server with **full** Express compatibility, based on µWebSockets.
4
-
5
- This library is a very fast re-implementation of Express.js 4.
6
- It is designed to be a drop-in replacement for Express.js, with the same API and functionality, while being much faster. It is not a fork of Express.js.
7
- To make sure µExpress matches behavior of Express in all cases, we run all tests with Express first, and then with µExpress and compare results to make sure they match.
8
-
9
- `npm install ultimate-express` -> replace `express` with `ultimate-express` -> done[*](https://github.com/dimdenGD/ultimate-express?tab=readme-ov-file#differences-from-express)
10
-
11
- [![Node.js >= 16.0.0](https://img.shields.io/badge/Node.js-%3E=16.0.0-green)](https://nodejs.org)
12
- [![npm](https://img.shields.io/npm/v/ultimate-express?label=last+version)](https://npmjs.com/package/ultimate-express)
13
- [![Patreon](https://img.shields.io/badge/donate-Patreon-orange)](https://patreon.com/dimdendev)
14
-
15
- ## Difference from similar projects
16
-
17
- Similar projects based on uWebSockets:
18
-
19
- - `express` on Bun - since Bun uses uWS for its HTTP module, Express is about 2-3 times faster than on Node.js, but still slower than µExpress because it doesn't do uWS-specific optimizations.
20
- - `hyper-express` - while having a similar API to Express, it's very far from being a drop-in replacement, and implements most of the functionality differently. This creates a lot of random quirks and issues, making the switch quite difficult. Built in middlewares are also very different, middlewares for Express are mostly not supported.
21
- - `uwebsockets-express` - this library is closer to being a drop-in replacement, but misses a lot of APIs, depends on Express by calling it's methods under the hood and doesn't try to optimize routing by using native uWS router.
22
-
23
- ## Performance
24
-
25
- ### Test results
26
-
27
- Tested using [wrk](https://github.com/wg/wrk) (`-d 60 -t 1 -c 200`). Etag was disabled in both Express and µExpress. Tested on Ubuntu 22.04, Node.js 20.17.0, AMD Ryzen 5 3600, 64GB RAM.
28
-
29
- | Test | Express req/sec | µExpress req/sec | Express throughput | µExpress throughput | µExpress speedup |
30
- | --------------------------------------------- | --------------- | ---------------- | ------------------ | ------------------- | ---------------- |
31
- | routing/simple-routes (/) | 11.16k | 70.75k | 2.08 MB/sec | 13.62 MB/sec | **6.34X** |
32
- | routing/lot-of-routes (/999) | 4.63k | 51.37k | 0.84 MB/sec | 9.45 MB/sec | **11.10X** |
33
- | routing/some-middlewares (/90) | 10.12k | 61.92k | 1.79 MB/sec | 11.32 MB/sec | **6.12X** |
34
- | routers/nested-routers (/abccc/nested/ddd) | 10.18k | 51.15k | 1.82 MB/sec | 9.40 MB/sec | **5.02X** |
35
- | middlewares/express-static (/static/index.js) | 6.58k | 32.45k | 10.15 MB/sec | 49.43 MB/sec | **4.87X** |
36
- | engines/ejs (/test) | 5.50k | 40.82k | 2.45 MB/sec | 18.38 MB/sec | **7.42X** |
37
- | middlewares/body-urlencoded (/abc) | 8.07k | 50.52k | 1.68 MB/sec | 10.78 MB/sec | **6.26X** |
38
-
39
- ### Performance against other frameworks
40
-
41
- Tested using [bun-http-framework-benchmark](https://github.com/dimdenGD/bun-http-framework-benchmark). This table only includes Node.js results.
42
- For full table with other runtimes, check [here](https://github.com/dimdenGD/bun-http-framework-benchmark?tab=readme-ov-file#results).
43
-
44
- | Framework | Average | Ping | Query | Body |
45
- | -------------------- | -------------- | ------------- | ------------- | ------------- |
46
- | uws | 94,296.49 | 108,551.92 | 104,756.22 | 69,581.33 |
47
- | hyper-express | 66,356.707 | 80,002.53 | 69,953.76 | 49,113.83 |
48
- | **ultimate-express** | **57,343.813** | **64,608.03** | **60,234.78** | **47,188.63** |
49
- | h3 | 35,423.263 | 41,243.68 | 34,429.26 | 30,596.85 |
50
- | fastify | 33,094.62 | 40,147.67 | 40,076.35 | 19,059.84 |
51
- | hono | 26,576.02 | 36,215.35 | 34,656.12 | 8,856.59 |
52
- | koa | 24,045.08 | 28,202.12 | 24,590.84 | 19,342.28 |
53
- | express | 10,411.313 | 11,245.57 | 10,598.74 | 9,389.63 |
54
-
55
- ### Performance on real-world application
56
-
57
- Also tested on a [real-world application](https://nekoweb.org) with templates, static files and dynamic pages with data from database, and showed 1.5-4X speedup in requests per second depending on the page.
58
-
59
- ## Differences from Express
60
-
61
- In a lot of cases, you can just replace `require("express")` with `require("ultimate-express")` and everything works the same. But there are some differences:
62
-
63
- - `case sensitive routing` is enabled by default.
64
- - request body is only read for POST, PUT and PATCH requests by default. You can add additional methods by setting `body methods` to array with uppercased methods.
65
- - For HTTPS, instead of doing this:
66
- ```js
67
- const https = require("https");
68
- const express = require("express");
69
-
70
- const app = express();
71
-
72
- https.createServer({
73
- key: fs.readFileSync('path/to/key.pem'),
74
- cert: fs.readFileSync('path/to/cert.pem')
75
- }, app).listen(3000, () => {
76
- console.log('Server is running on port 3000');
77
- });
78
- ```
79
-
80
- You have to pass `uwsOptions` to the `express()` constructor:
81
- ```js
82
- const express = require("u-express");
83
-
84
- const app = express({
85
- uwsOptions: {
86
- // https://unetworking.github.io/uWebSockets.js/generated/interfaces/AppOptions.html
87
- key_file_name: 'path/to/key.pem',
88
- cert_file_name: 'path/to/cert.pem'
89
- }
90
- });
91
-
92
- app.listen(3000, () => {
93
- console.log('Server is running on port 3000');
94
- });
95
- ```
96
-
97
- - This also applies to non-SSL HTTP too. Do not create http server manually, use `app.listen()` instead.
98
-
99
- ## Performance tips
100
-
101
- 1. µExpress tries to optimize routing as much as possible, but it's only possible if:
102
- - `case sensitive routing` is enabled (it is by default, unlike in normal Express).
103
- - only string paths without regex characters like *, +, (), {}, etc. can be optimized.
104
- - only 1-level deep routers can be optimized.
105
-
106
- Optimized routes can be up to 10 times faster than normal routes, as they're using native uWS router and have pre-calculated path.
107
-
108
- 2. Do not use external `serve-static` module. Instead use built-in `express.static()` middleware, which is optimized for uExpress.
109
-
110
- 3. Do not use `body-parser` module. Instead use built-in `express.text()`, `express.json()` etc.
111
-
112
- 4. Do not set `body methods` to read body of requests with GET method or other methods that don't need a body. Reading body makes endpoint about 15% slower.
113
-
114
- 5. By default, µExpress creates 1 (or 0 if your CPU has only 1 core) child thread to improve performance of reading files. You can change this number by setting `threads` to a different number in `express()`, or set to 0 to disable thread pool (`express({ threads: 0 })`). Threads are shared between all express() instances, with largest `threads` number being used. Using more threads will not necessarily improve performance. Sometimes not using threads at all is faster, please [test](https://github.com/wg/wrk/) both options.
115
-
116
- 6. Don't read `req.connection.remoteAddress` (or `req.ip` if `trust proxy` is disabled) after response is finished. In general, reading IP in uWS is quite slow (~15% slower), and you should only read it when you need it while request is still open. If you'll read it after response, it'll make µExpress read IP for every single request after, even when it's not needed.
117
-
118
- ## WebSockets
119
-
120
- Since you don't create http server manually, you can't properly use http.on("upgrade") to handle WebSockets. To solve this, there's currently 2 options:
121
-
122
- - There's currently another library in works: [Ultimate WS](https://github.com/dimdenGD/ultimate-ws) that implements `ws` module. It's same concept as this library, but for WebSockets: fast drop-in replacement for `ws` module with support for uExpress upgrades.
123
- - You can simply use `app.uwsApp` to access uWebSockets.js `App` instance and call its `ws()` method directly.
124
-
125
- ## Compatibility
126
-
127
- In general, basically all features and options are supported. Use [Express 4.x documentation](https://expressjs.com/en/4x/api.html) for API reference.
128
-
129
- ✅ - Full support (all features and options are supported)
130
- 🚧 - Partial support (some options are not supported)
131
- ❌ - Not supported
132
-
133
- ### express
134
-
135
- - ✅ express()
136
- - ✅ express.Router()
137
- - ✅ express.json()
138
- - ✅ express.urlencoded()
139
- - ✅ express.static()
140
- - ✅ express.text()
141
- - ✅ express.raw()
142
- - 🚧 express.request (this is not a constructor but a prototype for replacing methods)
143
- - 🚧 express.response (this is not a constructor but a prototype for replacing methods)
144
-
145
- ### Application
146
-
147
- - ✅ app.listen()
148
- - ✅ app.METHOD() (app.get, app.post, etc.)
149
- - ✅ app.route()
150
- - ✅ app.all()
151
- - ✅ app.use()
152
- - ✅ app.mountpath
153
- - ✅ app.set()
154
- - ✅ app.get()
155
- - ✅ app.enable()
156
- - ✅ app.disable()
157
- - ✅ app.enabled()
158
- - ✅ app.disabled()
159
- - ✅ app.path()
160
- - ✅ app.param(name, callback)
161
- - ✅ app.param(callback)
162
- - ✅ app.engine()
163
- - ✅ app.render()
164
- - ✅ app.locals
165
- - ✅ app.settings
166
- - ✅ app.engines
167
- - ✅ app.on("mount")
168
- - ✅ HEAD method
169
-
170
- ### Application settings
171
-
172
- - ✅ case sensitive routing
173
- - ✅ env
174
- - ✅ etag
175
- - ✅ jsonp callback name
176
- - ✅ json escape
177
- - ✅ json replacer
178
- - ✅ json spaces
179
- - ✅ query parser
180
- - ✅ strict routing
181
- - ✅ subdomain offset
182
- - ✅ trust proxy
183
- - ✅ views
184
- - ✅ view cache
185
- - ✅ view engine
186
- - ✅ x-powered-by
187
-
188
- ### Request
189
- - ✅ implements Readable stream
190
- - ✅ req.app
191
- - ✅ req.baseUrl
192
- - ✅ req.body
193
- - ✅ req.cookies
194
- - ✅ req.fresh
195
- - ✅ req.hostname
196
- - ✅ req.headers
197
- - ✅ req.headersDistinct
198
- - ✅ req.rawHeaders
199
- - ✅ req.ip
200
- - ✅ req.ips
201
- - ✅ req.method
202
- - ✅ req.url
203
- - ✅ req.originalUrl
204
- - ✅ req.params
205
- - ✅ req.path
206
- - ✅ req.protocol
207
- - ✅ req.query
208
- - ✅ req.res
209
- - ✅ req.secure
210
- - ✅ req.signedCookies
211
- - ✅ req.stale
212
- - ✅ req.subdomains
213
- - ✅ req.xhr
214
- - 🚧 req.route (route implementation is different from Express)
215
- - 🚧 req.connection, req.socket (only `encrypted`, `remoteAddress`, `localPort` and `remotePort` are supported)
216
- - ✅ req.accepts()
217
- - ✅ req.acceptsCharsets()
218
- - ✅ req.acceptsEncodings()
219
- - ✅ req.acceptsLanguages()
220
- - ✅ req.get()
221
- - ✅ req.is()
222
- - ✅ req.param()
223
- - ✅ req.range()
224
-
225
- ### Response
226
-
227
- - ✅ implements Writable stream
228
- - ✅ res.app
229
- - ✅ res.headersSent
230
- - ✅ res.req
231
- - ✅ res.locals
232
- - ✅ res.append()
233
- - ✅ res.attachment()
234
- - ✅ res.cookie()
235
- - ✅ res.clearCookie()
236
- - ✅ res.download()
237
- - ✅ res.end()
238
- - ✅ res.format()
239
- - ✅ res.getHeader(), res.get()
240
- - ✅ res.json()
241
- - ✅ res.jsonp()
242
- - ✅ res.links()
243
- - ✅ res.location()
244
- - ✅ res.redirect()
245
- - ✅ res.render()
246
- - ✅ res.send()
247
- - ✅ res.sendFile()
248
- - - ✅ options.maxAge
249
- - - ✅ options.root
250
- - - ✅ options.lastModified
251
- - - ✅ options.headers
252
- - - ✅ options.dotfiles
253
- - - ✅ options.acceptRanges
254
- - - ✅ options.cacheControl
255
- - - ✅ options.immutable
256
- - - ✅ Range header
257
- - - ✅ Setting ETag header
258
- - - ✅ If-Match header
259
- - - ✅ If-Modified-Since header
260
- - - ✅ If-Unmodified-Since header
261
- - - ✅ If-Range header
262
- - ✅ res.sendStatus()
263
- - ✅ res.header(), res.setHeader(), res.set()
264
- - ✅ res.status()
265
- - ✅ res.type()
266
- - ✅ res.vary()
267
- - ✅ res.removeHeader()
268
- - ✅ res.write()
269
- - ✅ res.writeHead()
270
-
271
- ### Router
272
-
273
- - ✅ router.all()
274
- - ✅ router.METHOD() (router.get, router.post, etc.)
275
- - ✅ router.route()
276
- - ✅ router.use()
277
- - ✅ router.param(name, callback)
278
- - ✅ router.param(callback)
279
- - ✅ options.caseSensitive
280
- - ✅ options.strict
281
- - ✅ options.mergeParams
282
-
283
- ## Tested middlewares
284
-
285
- Most of the middlewares that are compatible with Express are compatible with µExpress. Here's list of middlewares that we test for compatibility:
286
-
287
- - ✅ [body-parser](https://npmjs.com/package/body-parser) (use `express.text()` etc instead for better performance)
288
- - ✅ [cookie-parser](https://npmjs.com/package/cookie-parser)
289
- - ✅ [cookie-session](https://npmjs.com/package/cookie-session)
290
- - ✅ [serve-static](https://npmjs.com/package/serve-static) (use `express.static()` instead for better performance)
291
- - ✅ [serve-index](https://npmjs.com/package/serve-index)
292
- - ✅ [cors](https://npmjs.com/package/cors)
293
- - ✅ [errorhandler](https://npmjs.com/package/errorhandler)
294
- - ✅ [method-override](https://npmjs.com/package/method-override)
295
- - ✅ [multer](https://npmjs.com/package/multer)
296
- - ✅ [response-time](https://npmjs.com/package/response-time)
297
- - ✅ [express-fileupload](https://npmjs.com/package/express-fileupload)
298
- - ✅ [express-session](https://npmjs.com/package/express-session)
299
- - ✅ [express-rate-limit](https://npmjs.com/package/express-rate-limit)
300
- - ✅ [vhost](https://npmjs.com/package/vhost)
301
-
302
- Middlewares that are confirmed to not work:
303
-
304
- - ❌ [compression](https://npmjs.com/package/compression) (doesn't error, but doesn't compress)
305
-
306
- ## Tested view engines
307
-
308
- Any Express view engine should work. Here's list of engines we include in our test suite:
309
-
310
- - ✅ [ejs](https://npmjs.com/package/ejs)
311
- - ✅ [pug](https://npmjs.com/package/pug)
312
- - ✅ [express-dot-engine](https://npmjs.com/package/express-dot-engine)
313
- - ✅ [express-art-template](https://npmjs.com/package/express-art-template)
314
- - ✅ [express-handlebars](https://npmjs.com/package/express-handlebars)
1
+ # µExpress / Ultimate Express
2
+
3
+ The *Ultimate* Express. Fastest http server with **full** Express compatibility, based on µWebSockets.
4
+
5
+ This library is a very fast re-implementation of Express.js 4.
6
+ It is designed to be a drop-in replacement for Express.js, with the same API and functionality, while being much faster. It is not a fork of Express.js.
7
+ To make sure µExpress matches behavior of Express in all cases, we run all tests with Express first, and then with µExpress and compare results to make sure they match.
8
+
9
+ `npm install ultimate-express` -> replace `express` with `ultimate-express` -> done[*](https://github.com/dimdenGD/ultimate-express?tab=readme-ov-file#differences-from-express)
10
+
11
+ [![Node.js >= 16.0.0](https://img.shields.io/badge/Node.js-%3E=16.0.0-green)](https://nodejs.org)
12
+ [![npm](https://img.shields.io/npm/v/ultimate-express?label=last+version)](https://npmjs.com/package/ultimate-express)
13
+ [![Patreon](https://img.shields.io/badge/donate-Patreon-orange)](https://patreon.com/dimdendev)
14
+
15
+ ## Difference from similar projects
16
+
17
+ Similar projects based on uWebSockets:
18
+
19
+ - `express` on Bun - since Bun uses uWS for its HTTP module, Express is about 2-3 times faster than on Node.js, but still slower than µExpress because it doesn't do uWS-specific optimizations.
20
+ - `hyper-express` - while having a similar API to Express, it's very far from being a drop-in replacement, and implements most of the functionality differently. This creates a lot of random quirks and issues, making the switch quite difficult. Built in middlewares are also very different, middlewares for Express are mostly not supported.
21
+ - `uwebsockets-express` - this library is closer to being a drop-in replacement, but misses a lot of APIs, depends on Express by calling it's methods under the hood and doesn't try to optimize routing by using native uWS router.
22
+
23
+ ## Performance
24
+
25
+ ### Test results
26
+
27
+ Tested using [wrk](https://github.com/wg/wrk) (`-d 60 -t 1 -c 200`). Etag was disabled in both Express and µExpress. Tested on Ubuntu 22.04, Node.js 20.17.0, AMD Ryzen 5 3600, 64GB RAM.
28
+
29
+ | Test | Express req/sec | µExpress req/sec | Express throughput | µExpress throughput | µExpress speedup |
30
+ | --------------------------------------------- | --------------- | ---------------- | ------------------ | ------------------- | ---------------- |
31
+ | routing/simple-routes (/) | 11.16k | 75.14k | 2.08 MB/sec | 14.46 MB/sec | **6.73X** |
32
+ | routing/lot-of-routes (/999) | 4.63k | 54.57k | 0.84 MB/sec | 10.03 MB/sec | **11.78X** |
33
+ | routing/some-middlewares (/90) | 10.12k | 61.92k | 1.79 MB/sec | 11.32 MB/sec | **6.12X** |
34
+ | routers/nested-routers (/abccc/nested/ddd) | 10.18k | 51.15k | 1.82 MB/sec | 9.40 MB/sec | **5.02X** |
35
+ | middlewares/express-static (/static/index.js) | 6.58k | 32.45k | 10.15 MB/sec | 49.43 MB/sec | **4.87X** |
36
+ | engines/ejs (/test) | 5.50k | 40.82k | 2.45 MB/sec | 18.38 MB/sec | **7.42X** |
37
+ | middlewares/body-urlencoded (/abc) | 8.07k | 50.52k | 1.68 MB/sec | 10.78 MB/sec | **6.26X** |
38
+
39
+ ### Performance against other frameworks
40
+
41
+ Tested using [bun-http-framework-benchmark](https://github.com/dimdenGD/bun-http-framework-benchmark). This table only includes Node.js results.
42
+ For full table with other runtimes, check [here](https://github.com/dimdenGD/bun-http-framework-benchmark?tab=readme-ov-file#results).
43
+
44
+ | Framework | Average | Ping | Query | Body |
45
+ | -------------------- | -------------- | ------------- | ------------- | ------------- |
46
+ | uws | 94,296.49 | 108,551.92 | 104,756.22 | 69,581.33 |
47
+ | hyper-express | 66,356.707 | 80,002.53 | 69,953.76 | 49,113.83 |
48
+ | **ultimate-express** | **57,343.813** | **64,608.03** | **60,234.78** | **47,188.63** |
49
+ | h3 | 35,423.263 | 41,243.68 | 34,429.26 | 30,596.85 |
50
+ | fastify | 33,094.62 | 40,147.67 | 40,076.35 | 19,059.84 |
51
+ | hono | 26,576.02 | 36,215.35 | 34,656.12 | 8,856.59 |
52
+ | koa | 24,045.08 | 28,202.12 | 24,590.84 | 19,342.28 |
53
+ | express | 10,411.313 | 11,245.57 | 10,598.74 | 9,389.63 |
54
+
55
+ ### Performance on real-world application
56
+
57
+ Also tested on a [real-world application](https://nekoweb.org) with templates, static files and dynamic pages with data from database, and showed 1.5-4X speedup in requests per second depending on the page.
58
+
59
+ ## Differences from Express
60
+
61
+ In a lot of cases, you can just replace `require("express")` with `require("ultimate-express")` and everything works the same. But there are some differences:
62
+
63
+ - `case sensitive routing` is enabled by default.
64
+ - request body is only read for POST, PUT and PATCH requests by default. You can add additional methods by setting `body methods` to array with uppercased methods.
65
+ - For HTTPS, instead of doing this:
66
+ ```js
67
+ const https = require("https");
68
+ const express = require("express");
69
+
70
+ const app = express();
71
+
72
+ https.createServer({
73
+ key: fs.readFileSync('path/to/key.pem'),
74
+ cert: fs.readFileSync('path/to/cert.pem')
75
+ }, app).listen(3000, () => {
76
+ console.log('Server is running on port 3000');
77
+ });
78
+ ```
79
+
80
+ You have to pass `uwsOptions` to the `express()` constructor:
81
+ ```js
82
+ const express = require("u-express");
83
+
84
+ const app = express({
85
+ uwsOptions: {
86
+ // https://unetworking.github.io/uWebSockets.js/generated/interfaces/AppOptions.html
87
+ key_file_name: 'path/to/key.pem',
88
+ cert_file_name: 'path/to/cert.pem'
89
+ }
90
+ });
91
+
92
+ app.listen(3000, () => {
93
+ console.log('Server is running on port 3000');
94
+ });
95
+ ```
96
+
97
+ - This also applies to non-SSL HTTP too. Do not create http server manually, use `app.listen()` instead.
98
+
99
+ ## Performance tips
100
+
101
+ 1. µExpress tries to optimize routing as much as possible, but it's only possible if:
102
+ - `case sensitive routing` is enabled (it is by default, unlike in normal Express).
103
+ - only string paths without regex characters like *, +, (), {}, etc. can be optimized.
104
+ - only 1-level deep routers can be optimized.
105
+
106
+ Optimized routes can be up to 10 times faster than normal routes, as they're using native uWS router and have pre-calculated path.
107
+
108
+ 2. Do not use external `serve-static` module. Instead use built-in `express.static()` middleware, which is optimized for uExpress.
109
+
110
+ 3. Do not use `body-parser` module. Instead use built-in `express.text()`, `express.json()` etc.
111
+
112
+ 4. Do not set `body methods` to read body of requests with GET method or other methods that don't need a body. Reading body makes endpoint about 15% slower.
113
+
114
+ 5. By default, µExpress creates 1 (or 0 if your CPU has only 1 core) child thread to improve performance of reading files. You can change this number by setting `threads` to a different number in `express()`, or set to 0 to disable thread pool (`express({ threads: 0 })`). Threads are shared between all express() instances, with largest `threads` number being used. Using more threads will not necessarily improve performance. Sometimes not using threads at all is faster, please [test](https://github.com/wg/wrk/) both options.
115
+
116
+ 6. Don't read `req.connection.remoteAddress` (or `req.ip` if `trust proxy` is disabled) after response is finished. In general, reading IP in uWS is quite slow (~15% slower), and you should only read it when you need it while request is still open. If you'll read it after response, it'll make µExpress read IP for every single request after, even when it's not needed.
117
+
118
+ ## WebSockets
119
+
120
+ Since you don't create http server manually, you can't properly use http.on("upgrade") to handle WebSockets. To solve this, there's currently 2 options:
121
+
122
+ - There's currently another library in works: [Ultimate WS](https://github.com/dimdenGD/ultimate-ws) that implements `ws` module. It's same concept as this library, but for WebSockets: fast drop-in replacement for `ws` module with support for uExpress upgrades.
123
+ - You can simply use `app.uwsApp` to access uWebSockets.js `App` instance and call its `ws()` method directly.
124
+
125
+ ## Compatibility
126
+
127
+ In general, basically all features and options are supported. Use [Express 4.x documentation](https://expressjs.com/en/4x/api.html) for API reference.
128
+
129
+ ✅ - Full support (all features and options are supported)
130
+ 🚧 - Partial support (some options are not supported)
131
+ ❌ - Not supported
132
+
133
+ ### express
134
+
135
+ - ✅ express()
136
+ - ✅ express.Router()
137
+ - ✅ express.json()
138
+ - ✅ express.urlencoded()
139
+ - ✅ express.static()
140
+ - ✅ express.text()
141
+ - ✅ express.raw()
142
+ - 🚧 express.request (this is not a constructor but a prototype for replacing methods)
143
+ - 🚧 express.response (this is not a constructor but a prototype for replacing methods)
144
+
145
+ ### Application
146
+
147
+ - ✅ app.listen()
148
+ - ✅ app.METHOD() (app.get, app.post, etc.)
149
+ - ✅ app.route()
150
+ - ✅ app.all()
151
+ - ✅ app.use()
152
+ - ✅ app.mountpath
153
+ - ✅ app.set()
154
+ - ✅ app.get()
155
+ - ✅ app.enable()
156
+ - ✅ app.disable()
157
+ - ✅ app.enabled()
158
+ - ✅ app.disabled()
159
+ - ✅ app.path()
160
+ - ✅ app.param(name, callback)
161
+ - ✅ app.param(callback)
162
+ - ✅ app.engine()
163
+ - ✅ app.render()
164
+ - ✅ app.locals
165
+ - ✅ app.settings
166
+ - ✅ app.engines
167
+ - ✅ app.on("mount")
168
+ - ✅ HEAD method
169
+
170
+ ### Application settings
171
+
172
+ - ✅ case sensitive routing
173
+ - ✅ env
174
+ - ✅ etag
175
+ - ✅ jsonp callback name
176
+ - ✅ json escape
177
+ - ✅ json replacer
178
+ - ✅ json spaces
179
+ - ✅ query parser
180
+ - ✅ strict routing
181
+ - ✅ subdomain offset
182
+ - ✅ trust proxy
183
+ - ✅ views
184
+ - ✅ view cache
185
+ - ✅ view engine
186
+ - ✅ x-powered-by
187
+
188
+ ### Request
189
+ - ✅ implements Readable stream
190
+ - ✅ req.app
191
+ - ✅ req.baseUrl
192
+ - ✅ req.body
193
+ - ✅ req.cookies
194
+ - ✅ req.fresh
195
+ - ✅ req.hostname
196
+ - ✅ req.headers
197
+ - ✅ req.headersDistinct
198
+ - ✅ req.rawHeaders
199
+ - ✅ req.ip
200
+ - ✅ req.ips
201
+ - ✅ req.method
202
+ - ✅ req.url
203
+ - ✅ req.originalUrl
204
+ - ✅ req.params
205
+ - ✅ req.path
206
+ - ✅ req.protocol
207
+ - ✅ req.query
208
+ - ✅ req.res
209
+ - ✅ req.secure
210
+ - ✅ req.signedCookies
211
+ - ✅ req.stale
212
+ - ✅ req.subdomains
213
+ - ✅ req.xhr
214
+ - 🚧 req.route (route implementation is different from Express)
215
+ - 🚧 req.connection, req.socket (only `encrypted`, `remoteAddress`, `localPort` and `remotePort` are supported)
216
+ - ✅ req.accepts()
217
+ - ✅ req.acceptsCharsets()
218
+ - ✅ req.acceptsEncodings()
219
+ - ✅ req.acceptsLanguages()
220
+ - ✅ req.get()
221
+ - ✅ req.is()
222
+ - ✅ req.param()
223
+ - ✅ req.range()
224
+
225
+ ### Response
226
+
227
+ - ✅ implements Writable stream
228
+ - ✅ res.app
229
+ - ✅ res.headersSent
230
+ - ✅ res.req
231
+ - ✅ res.locals
232
+ - ✅ res.append()
233
+ - ✅ res.attachment()
234
+ - ✅ res.cookie()
235
+ - ✅ res.clearCookie()
236
+ - ✅ res.download()
237
+ - ✅ res.end()
238
+ - ✅ res.format()
239
+ - ✅ res.getHeader(), res.get()
240
+ - ✅ res.json()
241
+ - ✅ res.jsonp()
242
+ - ✅ res.links()
243
+ - ✅ res.location()
244
+ - ✅ res.redirect()
245
+ - ✅ res.render()
246
+ - ✅ res.send()
247
+ - ✅ res.sendFile()
248
+ - - ✅ options.maxAge
249
+ - - ✅ options.root
250
+ - - ✅ options.lastModified
251
+ - - ✅ options.headers
252
+ - - ✅ options.dotfiles
253
+ - - ✅ options.acceptRanges
254
+ - - ✅ options.cacheControl
255
+ - - ✅ options.immutable
256
+ - - ✅ Range header
257
+ - - ✅ Setting ETag header
258
+ - - ✅ If-Match header
259
+ - - ✅ If-Modified-Since header
260
+ - - ✅ If-Unmodified-Since header
261
+ - - ✅ If-Range header
262
+ - ✅ res.sendStatus()
263
+ - ✅ res.header(), res.setHeader(), res.set()
264
+ - ✅ res.status()
265
+ - ✅ res.type()
266
+ - ✅ res.vary()
267
+ - ✅ res.removeHeader()
268
+ - ✅ res.write()
269
+ - ✅ res.writeHead()
270
+
271
+ ### Router
272
+
273
+ - ✅ router.all()
274
+ - ✅ router.METHOD() (router.get, router.post, etc.)
275
+ - ✅ router.route()
276
+ - ✅ router.use()
277
+ - ✅ router.param(name, callback)
278
+ - ✅ router.param(callback)
279
+ - ✅ options.caseSensitive
280
+ - ✅ options.strict
281
+ - ✅ options.mergeParams
282
+
283
+ ## Tested middlewares
284
+
285
+ Almost all middlewares that are compatible with Express are compatible with µExpress. Here's list of middlewares that we test for compatibility:
286
+
287
+ - ✅ [body-parser](https://npmjs.com/package/body-parser) (use `express.text()` etc instead for better performance)
288
+ - ✅ [cookie-parser](https://npmjs.com/package/cookie-parser)
289
+ - ✅ [cookie-session](https://npmjs.com/package/cookie-session)
290
+ - ✅ [serve-static](https://npmjs.com/package/serve-static) (use `express.static()` instead for better performance)
291
+ - ✅ [serve-index](https://npmjs.com/package/serve-index)
292
+ - ✅ [cors](https://npmjs.com/package/cors)
293
+ - ✅ [errorhandler](https://npmjs.com/package/errorhandler)
294
+ - ✅ [method-override](https://npmjs.com/package/method-override)
295
+ - ✅ [multer](https://npmjs.com/package/multer)
296
+ - ✅ [response-time](https://npmjs.com/package/response-time)
297
+ - ✅ [express-fileupload](https://npmjs.com/package/express-fileupload)
298
+ - ✅ [express-session](https://npmjs.com/package/express-session)
299
+ - ✅ [express-rate-limit](https://npmjs.com/package/express-rate-limit)
300
+ - ✅ [vhost](https://npmjs.com/package/vhost)
301
+
302
+ Middlewares that are confirmed to not work:
303
+
304
+ - ❌ [compression](https://npmjs.com/package/compression) (doesn't error, but doesn't compress)
305
+
306
+ ## Tested view engines
307
+
308
+ Any Express view engine should work. Here's list of engines we include in our test suite:
309
+
310
+ - ✅ [ejs](https://npmjs.com/package/ejs)
311
+ - ✅ [pug](https://npmjs.com/package/pug)
312
+ - ✅ [express-dot-engine](https://npmjs.com/package/express-dot-engine)
313
+ - ✅ [express-art-template](https://npmjs.com/package/express-art-template)
314
+ - ✅ [express-handlebars](https://npmjs.com/package/express-handlebars)
315
315
  - ✅ [swig](https://npmjs.com/package/swig)