Node v20.4.0 (Current)

Oleh Rafael Gonzaga,

Notable Changes

Mock Timers

The new feature allows developers to write more reliable and predictable tests for time-dependent functionality. It includes MockTimers with the ability to mock setTimeout, setInterval from globals, node:timers, and node:timers/promises.

The feature provides a simple API to advance time, enable specific timers, and release all timers.

import assert from 'node:assert';
import { test } from 'node:test';

test('mocks setTimeout to be executed synchronously without having to actually wait for it', context => {
  const fn = context.mock.fn();
  // Optionally choose what to mock
  context.mock.timers.enable(['setTimeout']);
  const nineSecs = 9000;
  setTimeout(fn, nineSecs);

  const threeSeconds = 3000;
  context.mock.timers.tick(threeSeconds);
  context.mock.timers.tick(threeSeconds);
  context.mock.timers.tick(threeSeconds);

  assert.strictEqual(fn.mock.callCount(), 1);
});

This feature was contributed by Erick Wendel in #47775.

Support to the explicit resource management proposal

Node is adding support to the explicit resource management proposal to its resources allowing users of TypeScript/babel to use using/await using with V8 support for everyone else on the way.

This feature was contributed by Moshe Atlow and Benjamin Gruenbaum in #48518.

Other notable changes

  • [fe333d2584] - crypto: update root certificates to NSS 3.90 (Node.js GitHub Bot) #48416
  • [60c2ea4e79] - doc: add vmoroz to collaborators (Vladimir Morozov) #48527
  • [5cacdf9e6b] - doc: add kvakil to collaborators (Keyhan Vakil) #48449
  • [504d1d7bdc] - (SEMVER-MINOR) tls: add ALPNCallback server option for dynamic ALPN negotiation (Tim Perry) #45190

Commits

  • [8a611a387f] - benchmark: add bar.R (Rafael Gonzaga) #47729
  • [12fa716cf9] - benchmark: refactor crypto oneshot (Filip Skokan) #48267
  • [d6ecbde592] - benchmark: add crypto.create*Key (Filip Skokan) #48284
  • [e60b6dedd8] - bootstrap: unify snapshot builder and embedder entry points (Joyee Cheung) #48242
  • [40662957b1] - bootstrap: simplify initialization of source map handlers (Joyee Cheung) #48304
  • [6551538079] - build: fix configure --link-module (Richard Lau) #48522
  • [f7f32089e7] - build: sync libuv header change (Jiawen Geng) #48429
  • [f60205c915] - build: update action to close stale PRs (Michael Dawson) #48196
  • [4f4d0b802e] - child_process: improve spawn performance on Linux (Keyhan Vakil) #48523
  • [fe333d2584] - crypto: update root certificates to NSS 3.90 (Node.js GitHub Bot) #48416
  • [89aaf16237] - crypto: remove OPENSSL_FIPS guard for OpenSSL 3 (Richard Lau) #48392
  • [6199e1946c] - deps: upgrade to libuv 1.46.0 (Santiago Gimeno) #48618
  • [1b2b930fda] - deps: add loong64 config into openssl gypi (Shi Pujin) #48043
  • [ba8d048929] - deps: update acorn to 8.9.0 (Node.js GitHub Bot) #48484
  • [d96f921d06] - deps: update zlib to 1.2.13.1-motley-f81f385 (Node.js GitHub Bot) #48541
  • [ed1d047e8f] - deps: update googletest to ec4fed9 (Node.js GitHub Bot) #48538
  • [f43d718c67] - deps: update minimatch to 9.0.2 (Node.js GitHub Bot) #48542
  • [2f66147cbf] - deps: update corepack to 0.19.0 (Node.js GitHub Bot) #48540
  • [d91b0fde73] - deps: V8: cherry-pick 1a782f6543ae (Keyhan Vakil) #48523
  • [112335e342] - deps: update corepack to 0.18.1 (Node.js GitHub Bot) #48483
  • [2b141c413f] - deps: update icu to 73.2 (Node.js GitHub Bot) #48502
  • [188b34d4a1] - deps: upgrade npm to 9.7.2 (npm team) #48514
  • [bf0444b5d9] - deps: update zlib to 1.2.13.1-motley-3ca9f16 (Node.js GitHub Bot) #48413
  • [b339d80a56] - deps: upgrade npm to 9.7.1 (npm team) #48378
  • [4132931b87] - deps: update simdutf to 3.2.14 (Node.js GitHub Bot) #48344
  • [8cd56c1e85] - deps: update ada to 2.5.1 (Node.js GitHub Bot) #48319
  • [78cffcd645] - deps: update zlib to 982b036 (Node.js GitHub Bot) #48327
  • [6d00c2e33b] - doc: fix options order (Luigi Pinca) #48617
  • [7ad2d3a5d1] - doc: update security release stewards (Rafael Gonzaga) #48569
  • [cc3a056fdd] - doc: update return type for describe (Shrujal Shah) #48572
  • [99ae0b98af] - doc: run license-builder (github-actions[bot]) #48552
  • [9750d8205c] - doc: add description of autoAllocateChunkSize in ReadableStream (Debadree Chatterjee) #48004
  • [417927bb41] - doc: fix filename type in watch result (Dmitry Semigradsky) #48032
  • [ca2ae86bd7] - doc: unnest mime and MIMEParams from MIMEType constructor (Dmitry Semigradsky) #47950
  • [bda1228135] - doc: update security-release-process.md (Rafael Gonzaga) #48504
  • [60c2ea4e79] - doc: add vmoroz to collaborators (Vladimir Morozov) #48527
  • [37bc0eac4a] - doc: improve inspector.close() description (mary marchini) #48494
  • [2a403cdad5] - doc: link to Runtime Keys in export conditions (Jacob Hummer) #48408
  • [e2d579e644] - doc: update fs flags documentation (sinkhaha) #48463
  • [38bf290115] - doc: revise error.md introduction (Antoine du Hamel) #48423
  • [641a2e9c6d] - doc: add preveen-stack to triagers (Preveen P) #48387
  • [4ab5e8d2e3] - doc: refine when file is undefined in test events (Moshe Atlow) #48451
  • [5cacdf9e6b] - doc: add kvakil to collaborators (Keyhan Vakil) #48449
  • [b9c643e3ef] - doc: add additional info on TSFN dispatch (Michael Dawson) #48367
  • [17a0e1d1bf] - doc: add link for news from security wg (Michael Dawson) #48396
  • [3a62994a4f] - doc: fix typo in events.md (Darshan Sen) #48436
  • [e10a4cdf68] - doc: run license-builder (github-actions[bot]) #48336
  • [19fde638fd] - fs: call the callback with an error if writeSync fails (killa) #47949
  • [4cad9fd8bd] - fs: remove unneeded return statement (Luigi Pinca) #48526
  • [d367b73f43] - fs: use kResistStopPropagation (Chemi Atlow) #48521
  • [e50c3169af] - fs, stream: initial Symbol.dispose and Symbol.asyncDispose support (Moshe Atlow) #48518
  • [7d8a0b6eb7] - http: null the joinDuplicateHeaders property on cleanup (Luigi Pinca) #48608
  • [94ebb02f59] - http: server add async dispose (atlowChemi) #48548
  • [c6a69e31a3] - http: remove useless ternary in test (geekreal) #48481
  • [2f0f40328f] - http: fix for handling on boot timers headers and request (Franciszek Koltuniuk) #48291
  • [5378ad8ab1] - http2: server add asyncDispose (atlowChemi) #48548
  • [97a58c5970] - https: server add asyncDispose (atlowChemi) #48548
  • [40ae6eb6aa] - https: fix connection checking interval not clearing on server close (Nitzan Uziely) #48383
  • [15530fea4c] - lib: merge cjs and esm package json reader caches (Yagiz Nizipli) #48477
  • [32bda81c31] - lib: reduce url getters on makeRequireFunction (Yagiz Nizipli) #48492
  • [0da03f01ba] - lib: remove duplicated requires in check_syntax (Yagiz Nizipli) #48508
  • [97b00c347d] - lib: add option to force handling stopped events (Chemi Atlow) #48301
  • [fe16749649] - lib: fix output message when repl is used with pm (Rafael Gonzaga) #48438
  • [8c2c02d28a] - lib: create weakRef only if any signals provided (Chemi Atlow) #48448
  • [b6ae411ea9] - lib: remove obsolete deletion of bufferBinding.zeroFill (Chengzhong Wu) #47881
  • [562b3d4856] - lib: move web global bootstrapping to the expected file (Chengzhong Wu) #47881
  • [f9c0d5acac] - lib: fix blob.stream() causing hanging promises (Debadree Chatterjee) #48232
  • [0162a0f5bf] - lib: add support for inherited custom inspection methods (Antoine du Hamel) #48306
  • [159ab6627a] - lib: reduce URL invocations on http2 origins (Yagiz Nizipli) #48338
  • [f0709fdc59] - module: add SourceMap.findOrigin (Isaac Z. Schlueter) #47790
  • [4ec2d925b1] - module: reduce url invocations in esm/load.js (Yagiz Nizipli) #48337
  • [2c363971cc] - net: improve network family autoselection handle handling (Paolo Insogna) #48464
  • [dbf9e9ffc8] - node-api: provide napi_define_properties fast path (Gabriel Schulhof) #48440
  • [87ad657777] - node-api: implement external strings (Gabriel Schulhof) #48339
  • [4efa6807ea] - permission: handle end nodes with children cases (Rafael Gonzaga) #48531
  • [84fe811108] - repl: display dynamic import variant in static import error messages (Hemanth HM) #48129
  • [bdcc037470] - report: disable js stack when no context is entered (Chengzhong Wu) #48495
  • [97bd9ccd04] - src: fix uninitialized field access in AsyncHooks (Jan Olaf Krems) #48566
  • [404958fc96] - src: fix Coverity issue regarding unnecessary copy (Yagiz Nizipli) #48565
  • [c4b8edea24] - src: refactor SplitString in util (Yagiz Nizipli) #48491
  • [5bc13a4772] - src: revert IS_RELEASE (Rafael Gonzaga) #48505
  • [4971e46051] - src: add V8 fast api to guessHandleType (Yagiz Nizipli) #48349
  • [954e46e792] - src: return uint32 for guessHandleType (Yagiz Nizipli) #48349
  • [05009675da] - src: make realm binding data store weak (Chengzhong Wu) #47688
  • [120ac74352] - src: remove aliased buffer weak callback (Chengzhong Wu) #47688
  • [6591826e99] - src: handle wasm out of bound in osx will raise SIGBUS correctly (Congcong Cai) #46561
  • [1b84ddeec2] - src: implement constants binding directly (Joyee Cheung) #48186
  • [06d49c1f10] - src: implement natives binding without special casing (Joyee Cheung) #48186
  • [325441abf5] - src: add missing to_ascii method in dns queries (Daniel Lemire) #48354
  • [84d0eb74b8] - stream: fix premature pipeline end (Robert Nagy) #48435
  • [3df7368735] - test: add missing assertions to test-runner-cli (Moshe Atlow) #48593
  • [07eb310b0d] - test: remove test-crypto-keygen flaky designation (Luigi Pinca) #48575
  • [75aa0a7682] - test: remove test-timers-immediate-queue flaky designation (Luigi Pinca) #48575
  • [a9756f3126] - test: add Symbol.dispose support to mock timers (Benjamin Gruenbaum) #48549
  • [0f912a7248] - test: mark test-child-process-stdio-reuse-readable-stdio flaky (Luigi Pinca) #48537
  • [30f4bc4985] - test: make IsolateData per-isolate in cctest (Joyee Cheung) #48450
  • [407ce3fdcb] - test: define NAPI_VERSION before including node_api.h (Chengzhong Wu) #48376
  • [24a8fa95f0] - test: remove unnecessary noop function args to mustNotCall() (Antoine du Hamel) #48513
  • [09af579775] - test: skip test-runner-watch-mode on IBMi (Moshe Atlow) #48473
  • [77cb1ee0b2] - test: add missing <algorithm> include for std::find (Sam James) #48380
  • [7c790ca03c] - test: fix flaky test-watch-mode (Moshe Atlow) #48147
  • [1398829746] - test: fix test-net-autoselectfamily for kernel without IPv6 support (Livia Medeiros) #48265
  • [764119ba4b] - test: update url web-platform tests (Yagiz Nizipli) #48319
  • [f1ead59629] - test: ignore the copied entry_point.c (Luigi Pinca) #48297
  • [fc5d1bddcb] - test: refactor test-gc-http-client-timeout (Luigi Pinca) #48292
  • [46a3d068a0] - test: update encoding web-platform tests (Yagiz Nizipli) #48320
  • [141e5aad83] - test: update FileAPI web-platform tests (Yagiz Nizipli) #48322
  • [83cfc67099] - test: update user-timing web-platform tests (Yagiz Nizipli) #48321
  • [2c56835a33] - test_runner: fixed test shorthands return type (Shocker) #48555
  • [7d01c8894a] - (SEMVER-MINOR) test_runner: add initial draft for fakeTimers (Erick Wendel) #47775
  • [de4f14c249] - test_runner: add enqueue and dequeue events (Moshe Atlow) #48428
  • [5ebe3a4ea7] - test_runner: make --test-name-pattern recursive (Moshe Atlow) #48382
  • [93bf447308] - test_runner: refactor coverage report output for readability (Damien Seguin) #47791
  • [504d1d7bdc] - (SEMVER-MINOR) tls: add ALPNCallback server option for dynamic ALPN negotiation (Tim Perry) #45190
  • [203c3cf4ca] - tools: update lint-md-dependencies (Node.js GitHub Bot) #48544
  • [333907b19d] - tools: speedup compilation of js2c output (Keyhan Vakil) #48160
  • [10bd5f4d97] - tools: update lint-md-dependencies (Node.js GitHub Bot) #48486
  • [52de27b9fe] - tools: pin ruff version number (Rich Trott) #48505
  • [4345526644] - tools: replace sed with perl (Luigi Pinca) #48499
  • [6c590835f3] - tools: automate update openssl v16 (Marco Ippolito) #48377
  • [90b5335338] - tools: update eslint to 8.43.0 (Node.js GitHub Bot) #48487
  • [cd83530a11] - tools: update doc to to-vfile@8.0.0 (Node.js GitHub Bot) #48485
  • [e500b439bd] - tools: prepare tools/doc for to-vfile 8.0.0 (Rich Trott) #48485
  • [d623616813] - tools: update lint-md-dependencies (Node.js GitHub Bot) #48417
  • [a2e107dde4] - tools: update create-or-update-pull-request-action (Richard Lau) #48398
  • [8009e2c3be] - tools: update eslint-plugin-jsdoc (Richard Lau) #48393
  • [10385c8565] - tools: add version update to external dependencies (Andrea Fassina) #48081
  • [b1cef81b18] - tools: update eslint to 8.42.0 (Node.js GitHub Bot) #48328
  • [0923dc0b8e] - tools: disable jsdoc/no-defaults rule (Luigi Pinca) #48328
  • [b03146da85] - typings: remove unused primordials (Yagiz Nizipli) #48509
  • [e9c9d187b9] - typings: fix JSDoc in ESM loader modules (Antoine du Hamel) #48424
  • [fafe651d23] - url: conform to origin getter spec changes (Yagiz Nizipli) #48319

Windows 32-bit Installer: https://nodejs.org/dist/v20.4.0/node-v20.4.0-x86.msi
Windows 64-bit Installer: https://nodejs.org/dist/v20.4.0/node-v20.4.0-x64.msi
Windows ARM 64-bit Installer: https://nodejs.org/dist/v20.4.0/node-v20.4.0-arm64.msi
Windows 32-bit Binary: https://nodejs.org/dist/v20.4.0/win-x86/node.exe
Windows 64-bit Binary: https://nodejs.org/dist/v20.4.0/win-x64/node.exe
Windows ARM 64-bit Binary: https://nodejs.org/dist/v20.4.0/win-arm64/node.exe
macOS 64-bit Installer: https://nodejs.org/dist/v20.4.0/node-v20.4.0.pkg
macOS Apple Silicon 64-bit Binary: https://nodejs.org/dist/v20.4.0/node-v20.4.0-darwin-arm64.tar.gz
macOS Intel 64-bit Binary: https://nodejs.org/dist/v20.4.0/node-v20.4.0-darwin-x64.tar.gz
Linux 64-bit Binary: https://nodejs.org/dist/v20.4.0/node-v20.4.0-linux-x64.tar.xz
Linux PPC LE 64-bit Binary: https://nodejs.org/dist/v20.4.0/node-v20.4.0-linux-ppc64le.tar.xz
Linux s390x 64-bit Binary: https://nodejs.org/dist/v20.4.0/node-v20.4.0-linux-s390x.tar.xz
AIX 64-bit Binary: https://nodejs.org/dist/v20.4.0/node-v20.4.0-aix-ppc64.tar.gz
ARMv7 32-bit Binary: https://nodejs.org/dist/v20.4.0/node-v20.4.0-linux-armv7l.tar.xz
ARMv8 64-bit Binary: https://nodejs.org/dist/v20.4.0/node-v20.4.0-linux-arm64.tar.xz
Source Code: https://nodejs.org/dist/v20.4.0/node-v20.4.0.tar.gz
Other release files: https://nodejs.org/dist/v20.4.0/
Documentation: https://nodejs.org/docs/v20.4.0/api/

SHASUMS

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

d41a6396dbb29dbeab84d8bc8916bf9ddb6564793f2ac907868023e0ed53bb5a  node-v20.4.0-aix-ppc64.tar.gz
aebab3e1a9a9e36cf42262f525440fa107f62f528681691c4640673e3b1d860e  node-v20.4.0-arm64.msi
34f51397b6aad957b1a8eb70d13da5baf357ead124c1e429a7e939aa61266c06  node-v20.4.0-darwin-arm64.tar.gz
60b39a297eb673ef07c8fbc620be545269a3bb3f13d0aefa50185bde0b0b0eb1  node-v20.4.0-darwin-arm64.tar.xz
fe765474a8651b85cee04a64e8473089196b922a36621f464a985a5f4891a054  node-v20.4.0-darwin-x64.tar.gz
5587e6dc98f5ac64ae568468419092c937fa4dec3af91d2d8a18b2255769a88f  node-v20.4.0-darwin-x64.tar.xz
7f917743676afae38f9027b2d8d8b85fbc0e213bf3dc7b0dc54de4d8a02f41d7  node-v20.4.0-headers.tar.gz
8a5f76a2fd6552f537461d1c2538a1a350b6b7ae38a1daa84fff74e3fab355e7  node-v20.4.0-headers.tar.xz
6ed340475a8bd5db5f04fe943b8fb89b7b2a8fd919f91217c6386dfa59865ba3  node-v20.4.0-linux-arm64.tar.gz
757f9c541f3e5da6e5ce06813d0ba206d4d013c008d7c59a7411512c1abfd0be  node-v20.4.0-linux-arm64.tar.xz
9b7e8d9ecffcb9039cb3cc7d51181f1f8ae9072a738787e5bb5994a8f3f548c3  node-v20.4.0-linux-armv7l.tar.gz
29f9d67081c3a811b02786d2a9f9288c2a576ec2cb8f62acfe294a8d62f6b1b7  node-v20.4.0-linux-armv7l.tar.xz
71bef4eb631ccd0129f14066ed963613f59772b1f804ad99e06f4d25a5178cf0  node-v20.4.0-linux-ppc64le.tar.gz
d7ef827dd81536f8c52eca6e2688574bff53328754ccbcf23ec0a49f366be2cc  node-v20.4.0-linux-ppc64le.tar.xz
0a60c9b6b9430a004a8dcbf31b59c41bd406ed7ed66fbf2537ffab58cb12d918  node-v20.4.0-linux-s390x.tar.gz
1a2fed46ad35821fb4a4e0a6ba0682a4cac76bd59c9bed271128da9b608933a8  node-v20.4.0-linux-s390x.tar.xz
2a9b03dd17fa6d9241b93e244d7e8f2524c4019fb5cfe3a99e59da1ee983cb9a  node-v20.4.0-linux-x64.tar.gz
6b49a007f409fb7620350285cfc909fbc909604fd0ff5a87a1730365514b3712  node-v20.4.0-linux-x64.tar.xz
5b787126a671595ea0b4aa03dc9c6aaaccb2f4f1649c171afd1c3fe70bf3e1f9  node-v20.4.0.pkg
ee5a8b8fc18e57e1613480f4d87734190b9d3873b9c4696badf74bbc8310469d  node-v20.4.0.tar.gz
09bd0b73c526b63c029d5ddfd885d10962e7ad87c975b94583c1f8ce90ee5348  node-v20.4.0.tar.xz
e5dc496965f5a5699d3c29ac8ee93574f051655d7c03201aba1419f7150087ad  node-v20.4.0-win-arm64.7z
ee84dba7bc7bf25977cca5bf83bf8fcab8e46f36efd7ccbe54e3d62eebb42518  node-v20.4.0-win-arm64.zip
97bf0aecb90aa5907fa4a7afdf8dde0a08f4f37043525c22a79d5f0512dfa4c1  node-v20.4.0-win-x64.7z
91a51aaa9152db510704b4274cffd84c6e3572e1678e055e0d9c5cf7951ebc2a  node-v20.4.0-win-x64.zip
61cf8648275341e5f144749d11779087d73aa9f58e059d08fce6edbb1217b49d  node-v20.4.0-win-x86.7z
d5483af890061e3b068077fa46d31a6948e62c3fb6bceaa6d453537de79cd126  node-v20.4.0-win-x86.zip
3e3ccf5f9c32e52a4f8631dfdbe5cc44eee9d891d05fdd8d0b1359f00b7f9013  node-v20.4.0-x64.msi
3db2515d260fd2568e715896044f7e3d41dc8a4d0a10604c77466c160096f59a  node-v20.4.0-x86.msi
691013e2f9687732ffbcfaaa5a59f6bad669266354f9da25088bc328ce5e70b1  win-arm64/node.exe
26977faa070f622c775ac338b51aae98a410b42e7eadeeecfc7f9893ead83d29  win-arm64/node.lib
13f10b8230ea61207589dcb075ab6706b1bf94b4c30e5b62cfbf62d34a047055  win-arm64/node_pdb.7z
aa91088403af0cf43d35272b9bd36e6a41effbbaef276c1e26cea0c04170de06  win-arm64/node_pdb.zip
8419696dafcdd2c8ab41a0e3cc3c731933f47beee3da8459d802ef53332b867c  win-x64/node.exe
634e16fe60b1c7a043c53cea124af0b4122e3a8d6cbda5130f58593dfae3d50b  win-x64/node.lib
f51c6b94dcb1c5f683255e89463b3bc909774a0d0f7d9117e68a688e535e3b4f  win-x64/node_pdb.7z
c2bd95feceaeae6e10f081d5d1c7beb0e619b3a9ca920ec01b952e48442e51ef  win-x64/node_pdb.zip
fc6d68673f6582c0ef04caad96ead0e40832e060fd89f483d442201c97a7e6ae  win-x86/node.exe
200b17477721475de86ddabbdecd5970c59723b74890c19398fdc47013593af5  win-x86/node.lib
0b7d7c7666bb81b008257a5cda9e2d5ba25d4a5623d87b62963ba221c8b12036  win-x86/node_pdb.7z
3dc2a339c5535218b79e95bfb5759c5e36757001e1236953da86f40e20855fb3  win-x86/node_pdb.zip
-----BEGIN PGP SIGNATURE-----

iQGzBAEBCAAdFiEEiQwI24V5Fi/uDfnbi+q0389VXvQFAmSldu8ACgkQi+q0389V
XvQrYQv9GJkxaG49BxIknAhkP05PF/H2HMqXy+jY9uJy9xAROsfBwKw8k+aMue7S
dF3xRZB3NIALZNptTDFoqu0GplcC0xUNPJr2/MAzVEX9neXEnzHtvfxd1bH/8wlz
sOUBB3degVeF/fcuWbbTA4Lq9MibAmVmm5YDXQjQpLC7jaWmuOqJvWz2qiqiP8d8
mLG+x7u36uGPXVkEFFwfjw8QabQ3FszQVM5vTbr1jdJsYUVd+k6ag9mOaRs0sB8O
CUC1ZYCXSf8CcTLziZLXB0GYMswR656LHJO7CrVgpRyi21SsF/z0f+XVjDdsrYtC
7yINviNo9Q1xBJYL5hrQYFxa8lg60ujOZIFwUfMu+S4ZSFROxHpS2x2vg93m8ON8
qbxWMx1H8dj7ubBOSOY3aXnC+WFDbt9TLu9CApvqZ27tsLjGhSi/mjNPqqT97Ek0
Bsf8o8BuAsWi3LOt11t5Mpn5H51GsLJ+9NvN5kMh0KgUgi/+qc5xeGbFUh8HaHU0
7sHCBsHg
=P4sp
-----END PGP SIGNATURE-----

Gulir ke atas