Skip to content

body-parsing

Example Code

typescript
import { Elysia } from "elysia";
import { inspect } from "node:util";
export default new Elysia().post("/parse", async ({ body }) => {
  return inspect(body);
});

Tests

Testbunnode
json
urlencoded
urlencoded_php_arrays_are_unsupported
urlencoded_duplicate_keys_become_array
multipart
file_upload
file_upload_multiple
plain_text
octet_stream
xml_is_treated_as_urlencoded
ndjson_is_treated_as_urlencoded

json

text
=== Test Execution ===
$ curl -s -D- "http://localhost:3000/parse" -X POST \
  -H "Content-Type: application/json" \
  -d '{"x":1,"a":[2,3],"o":{"b":{"j":"k"}}}'
HTTP/1.1 200 OK
content-type: text/plain;charset=utf-8
Date: Sun, 01 Jun 2025 08:00:17 GMT
Content-Length: 43

{ x: 1, a: [ 2, 3 ], o: { b: { j: 'k' } } }
✓ expect: 200
✓ expect: a: [ 2, 3 ]

=== Runtime Output ===
[runtime] Bun 1.2.15
Started development server: http://localhost:3000
text
=== Test Execution ===
$ curl -s -D- "http://localhost:3000/parse" -X POST \
  -H "Content-Type: application/json" \
  -d '{"x":1,"a":[2,3],"o":{"b":{"j":"k"}}}'
HTTP/1.1 200 OK
Content-Type: text/plain
Content-Length: 43
Date: Sun, 01 Jun 2025 08:00:18 GMT
Connection: keep-alive
Keep-Alive: timeout=5

{ x: 1, a: [ 2, 3 ], o: { b: { j: 'k' } } }
✓ expect: 200
✓ expect: a: [ 2, 3 ]

=== Runtime Output ===
(node:28) ExperimentalWarning: Type Stripping is an experimental feature and might change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
[runtime] Node v22.16.0
🦊 Elysia is running at :::3000

urlencoded

text
=== Test Execution ===
$ curl -s -D- "http://localhost:3000/parse" -X POST \
  -d x=1 -d y=2 -d z=3
HTTP/1.1 200 OK
content-type: text/plain;charset=utf-8
Date: Sun, 01 Jun 2025 11:16:55 GMT
Content-Length: 51

[Object: null prototype] { x: '1', y: '2', z: '3' }
✓ expect: 200
✓ expect: x: '1', y: '2', z: '3'

=== Runtime Output ===
[runtime] Bun 1.2.15
Started development server: http://localhost:3000
text
=== Test Execution ===
$ curl -s -D- "http://localhost:3000/parse" -X POST \
  -d x=1 -d y=2 -d z=3
HTTP/1.1 200 OK
Content-Type: text/plain
Content-Length: 51
Date: Sun, 01 Jun 2025 11:16:56 GMT
Connection: keep-alive
Keep-Alive: timeout=5

[Object: null prototype] { x: '1', y: '2', z: '3' }
✓ expect: 200
✓ expect: x: '1', y: '2', z: '3'

=== Runtime Output ===
(node:28) ExperimentalWarning: Type Stripping is an experimental feature and might change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
[runtime] Node v22.16.0
🦊 Elysia is running at :::3000

urlencoded_php_arrays_are_unsupported

text
=== Test Execution ===
$ curl -s -D- "http://localhost:3000/parse" -X POST \
  -d o[b][j]=k -d a[]=1
HTTP/1.1 200 OK
content-type: text/plain;charset=utf-8
Date: Sun, 01 Jun 2025 11:16:56 GMT
Content-Length: 55

[Object: null prototype] { 'o[b][j]': 'k', 'a[]': '1' }
✓ expect: 200
✓ expect: 'o[b][j]': 'k', 'a[]': '1'

=== Runtime Output ===
[runtime] Bun 1.2.15
Started development server: http://localhost:3000
text
=== Test Execution ===
$ curl -s -D- "http://localhost:3000/parse" -X POST \
  -d o[b][j]=k -d a[]=1
HTTP/1.1 200 OK
Content-Type: text/plain
Content-Length: 55
Date: Sun, 01 Jun 2025 11:16:57 GMT
Connection: keep-alive
Keep-Alive: timeout=5

[Object: null prototype] { 'o[b][j]': 'k', 'a[]': '1' }
✓ expect: 200
✓ expect: 'o[b][j]': 'k', 'a[]': '1'

=== Runtime Output ===
(node:27) ExperimentalWarning: Type Stripping is an experimental feature and might change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
[runtime] Node v22.16.0
🦊 Elysia is running at :::3000

urlencoded_duplicate_keys_become_array

text
=== Test Execution ===
$ curl -s -D- "http://localhost:3000/parse" -X POST \
  -d a=foo -d a=bar -d a=baz
HTTP/1.1 200 OK
content-type: text/plain;charset=utf-8
Date: Sun, 01 Jun 2025 11:16:56 GMT
Content-Length: 55

[Object: null prototype] { a: [ 'foo', 'bar', 'baz' ] }
✓ expect: 200
✓ expect: a: [ 'foo', 'bar', 'baz' ]

=== Runtime Output ===
[runtime] Bun 1.2.15
Started development server: http://localhost:3000
text
=== Test Execution ===
$ curl -s -D- "http://localhost:3000/parse" -X POST \
  -d a=foo -d a=bar -d a=baz
HTTP/1.1 200 OK
Content-Type: text/plain
Content-Length: 55
Date: Sun, 01 Jun 2025 11:16:58 GMT
Connection: keep-alive
Keep-Alive: timeout=5

[Object: null prototype] { a: [ 'foo', 'bar', 'baz' ] }
✓ expect: 200
✓ expect: a: [ 'foo', 'bar', 'baz' ]

=== Runtime Output ===
(node:28) ExperimentalWarning: Type Stripping is an experimental feature and might change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
[runtime] Node v22.16.0
🦊 Elysia is running at :::3000

multipart

text
=== Test Execution ===
$ curl -s -D- "http://localhost:3000/parse" -X POST \
  -F x=1 -F y=2 -F z=3 \
  -F a=foo -F a=bar -F a=baz
HTTP/1.1 200 OK
content-type: text/plain;charset=utf-8
Date: Sun, 01 Jun 2025 11:16:58 GMT
Content-Length: 54

{ x: '1', y: '2', z: '3', a: [ 'foo', 'bar', 'baz' ] }
✓ expect: 200
✓ expect: x: '1', y: '2', z: '3', a: [ 'foo', 'bar', 'baz' ]

=== Runtime Output ===
[runtime] Bun 1.2.15
Started development server: http://localhost:3000
text
=== Test Execution ===
$ curl -s -D- "http://localhost:3000/parse" -X POST \
  -F x=1 -F y=2 -F z=3 \
  -F a=foo -F a=bar -F a=baz
HTTP/1.1 200 OK
Content-Type: text/plain
Content-Length: 54
Date: Sun, 01 Jun 2025 11:22:21 GMT
Connection: keep-alive
Keep-Alive: timeout=5

{ x: '1', y: '2', z: '3', a: [ 'foo', 'bar', 'baz' ] }
✓ expect: 200
✓ expect: x: '1', y: '2', z: '3', a: [ 'foo', 'bar', 'baz' ]

=== Runtime Output ===
(node:26) ExperimentalWarning: Type Stripping is an experimental feature and might change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
[runtime] Node v22.16.0
🦊 Elysia is running at :::3000

file_upload

text
=== Test Execution ===
$ curl -s -D- "http://localhost:3000/parse" -X POST \
  -F file=@package.json
HTTP/1.1 200 OK
content-type: text/plain;charset=utf-8
Date: Sun, 01 Jun 2025 11:22:21 GMT
Content-Length: 17

{ file: Blob {} }
✓ expect: 200
✓ expect: file: 

=== Runtime Output ===
[runtime] Bun 1.2.15
Started development server: http://localhost:3000
text
=== Test Execution ===
$ curl -s -D- "http://localhost:3000/parse" -X POST \
  -F file=@package.json
HTTP/1.1 200 OK
Content-Type: text/plain
Content-Length: 134
Date: Sun, 01 Jun 2025 11:24:38 GMT
Connection: keep-alive
Keep-Alive: timeout=5

{
  file: File {
    size: 1172,
    type: 'application/octet-stream',
    name: 'package.json',
    lastModified: 1748777078072
  }
}
✓ expect: 200
✓ expect: file: 

=== Runtime Output ===
(node:27) ExperimentalWarning: Type Stripping is an experimental feature and might change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
[runtime] Node v22.16.0
🦊 Elysia is running at :::3000

file_upload_multiple

text
=== Test Execution ===
$ curl -s -D- "http://localhost:3000/parse" -X POST \
  -F file=@package.json \
  -F file=@tsconfig.json
HTTP/1.1 200 OK
content-type: text/plain;charset=utf-8
Date: Sun, 01 Jun 2025 11:22:22 GMT
Content-Length: 30

{ file: [ Blob {}, Blob {} ] }
✓ expect: 200
✓ expect: file: [

=== Runtime Output ===
[runtime] Bun 1.2.15
Started development server: http://localhost:3000
text
=== Test Execution ===
$ curl -s -D- "http://localhost:3000/parse" -X POST \
  -F file=@package.json \
  -F file=@tsconfig.json
HTTP/1.1 200 OK
Content-Type: text/plain
Content-Length: 291
Date: Sun, 01 Jun 2025 11:24:39 GMT
Connection: keep-alive
Keep-Alive: timeout=5

{
  file: [
    File {
      size: 1172,
      type: 'application/octet-stream',
      name: 'package.json',
      lastModified: 1748777079353
    },
    File {
      size: 45,
      type: 'application/octet-stream',
      name: 'tsconfig.json',
      lastModified: 1748777079353
    }
  ]
}
✓ expect: 200
✓ expect: file: [

=== Runtime Output ===
(node:28) ExperimentalWarning: Type Stripping is an experimental feature and might change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
[runtime] Node v22.16.0
🦊 Elysia is running at :::3000

plain_text

text
=== Test Execution ===
$ curl -s -D- "http://localhost:3000/parse" -X POST \
  -H "Content-Type: text/plain" \
  -d "hello, world"
HTTP/1.1 200 OK
content-type: text/plain;charset=utf-8
Date: Sun, 01 Jun 2025 11:17:00 GMT
Content-Length: 14

'hello, world'
✓ expect: 200
✓ expect: 'hello, world'

=== Runtime Output ===
[runtime] Bun 1.2.15
Started development server: http://localhost:3000
text
=== Test Execution ===
$ curl -s -D- "http://localhost:3000/parse" -X POST \
  -H "Content-Type: text/plain" \
  -d "hello, world"
HTTP/1.1 200 OK
Content-Type: text/plain
Content-Length: 14
Date: Sun, 01 Jun 2025 11:17:01 GMT
Connection: keep-alive
Keep-Alive: timeout=5

'hello, world'
✓ expect: 200
✓ expect: 'hello, world'

=== Runtime Output ===
(node:27) ExperimentalWarning: Type Stripping is an experimental feature and might change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
[runtime] Node v22.16.0
🦊 Elysia is running at :::3000

octet_stream

text
=== Test Execution ===
$ curl -s -D- "http://localhost:3000/parse" -X POST \
  -H "Content-Type: application/octet-stream" \
  -d "hello, world"
HTTP/1.1 200 OK
content-type: text/plain;charset=utf-8
Date: Sun, 01 Jun 2025 11:17:01 GMT
Content-Length: 90

ArrayBuffer {
  [Uint8Contents]: <68 65 6c 6c 6f 2c 20 77 6f 72 6c 64>,
  byteLength: 12
}
✓ expect: 200
✓ expect: ArrayBuffer

=== Runtime Output ===
[runtime] Bun 1.2.15
Started development server: http://localhost:3000
text
=== Test Execution ===
$ curl -s -D- "http://localhost:3000/parse" -X POST \
  -H "Content-Type: application/octet-stream" \
  -d "hello, world"
HTTP/1.1 200 OK
Content-Type: text/plain
Content-Length: 90
Date: Sun, 01 Jun 2025 11:17:01 GMT
Connection: keep-alive
Keep-Alive: timeout=5

ArrayBuffer {
  [Uint8Contents]: <68 65 6c 6c 6f 2c 20 77 6f 72 6c 64>,
  byteLength: 12
}
✓ expect: 200
✓ expect: ArrayBuffer

=== Runtime Output ===
(node:26) ExperimentalWarning: Type Stripping is an experimental feature and might change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
[runtime] Node v22.16.0
🦊 Elysia is running at :::3000

xml_is_treated_as_urlencoded

text
=== Test Execution ===
$ curl -s -D- "http://localhost:3000/parse" -X POST \
  -H "Content-Type: application/xml" \
  -d "<hello>world</hello>"
HTTP/1.1 200 OK
content-type: text/plain;charset=utf-8
Date: Sun, 01 Jun 2025 11:17:01 GMT
Content-Length: 55

[Object: null prototype] { '<hello>world</hello>': '' }
✓ expect: 200
✓ expect: '<hello>world</hello>': ''

=== Runtime Output ===
[runtime] Bun 1.2.15
Started development server: http://localhost:3000
text
=== Test Execution ===
$ curl -s -D- "http://localhost:3000/parse" -X POST \
  -H "Content-Type: application/xml" \
  -d "<hello>world</hello>"
HTTP/1.1 200 OK
Content-Type: text/plain
Content-Length: 55
Date: Sun, 01 Jun 2025 11:17:03 GMT
Connection: keep-alive
Keep-Alive: timeout=5

[Object: null prototype] { '<hello>world</hello>': '' }
✓ expect: 200
✓ expect: '<hello>world</hello>': ''

=== Runtime Output ===
(node:27) ExperimentalWarning: Type Stripping is an experimental feature and might change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
[runtime] Node v22.16.0
🦊 Elysia is running at :::3000

ndjson_is_treated_as_urlencoded

text
=== Test Execution ===
$ curl -s -D- "http://localhost:3000/parse" -X POST \
  -H "Content-Type: application/x-ndjson" \
  -d $'{"hello":"world"}\n{"foo":"bar"}\n'
HTTP/1.1 200 OK
content-type: text/plain;charset=utf-8
Date: Sun, 01 Jun 2025 11:24:41 GMT
Content-Length: 69

[Object: null prototype] { '{"hello":"world"}\n{"foo":"bar"}\n': '' }
✓ expect: 200
✓ expect: '{"hello":"world"}\n{"foo":"bar"}\n': ''

=== Runtime Output ===
[runtime] Bun 1.2.15
Started development server: http://localhost:3000
text
=== Test Execution ===
$ curl -s -D- "http://localhost:3000/parse" -X POST \
  -H "Content-Type: application/x-ndjson" \
  -d $'{"hello":"world"}\n{"foo":"bar"}\n'
HTTP/1.1 200 OK
Content-Type: text/plain
Content-Length: 69
Date: Sun, 01 Jun 2025 11:24:42 GMT
Connection: keep-alive
Keep-Alive: timeout=5

[Object: null prototype] { '{"hello":"world"}\n{"foo":"bar"}\n': '' }
✓ expect: 200
✓ expect: '{"hello":"world"}\n{"foo":"bar"}\n': ''

=== Runtime Output ===
(node:27) ExperimentalWarning: Type Stripping is an experimental feature and might change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
[runtime] Node v22.16.0
🦊 Elysia is running at :::3000