URL Encode JavaScript โ encodeURIComponent()
Gunakan URL Encode Online gratis langsung di browser Anda โ tidak perlu instalasi.
Coba URL Encode Online Online โSaat Anda membuat URL pencarian, meneruskan jalur redirect sebagai parameter query, atau menyusun permintaan otorisasi OAuth, karakter khusus seperti &, =, dan spasi akan merusak URL secara diam-diam kecuali Anda menyandikannya terlebih dahulu. JavaScript menawarkan tiga pendekatan bawaan โ encodeURIComponent(), encodeURI(), dan URLSearchParams โ masing-masing dirancang untuk kasus penggunaan yang berbeda, dan memilih yang salah adalah akar penyebab sebagian besar bug penyandian yang saya temui dalam tinjauan kode. Untuk penyandian cepat tanpa kode apa pun, Encoder URL ToolDeck menanganinya secara instan di browser. Panduan ini mencakup ketiga pendekatan secara mendalam (JavaScript ES2015+ / Node.js 10+): kapan menggunakan masing-masing, perbedaannya untuk spasi dan karakter khusus, pola Fetch dan API dunia nyata, penggunaan CLI, dan empat kesalahan yang menyebabkan bug produksi paling halus.
- โencodeURIComponent() adalah pilihan tepat untuk menyandikan nilai parameter individual โ fungsi ini menyandikan setiap karakter kecuali AโZ, aโz, 0โ9, dan - _ . ! ~ * ' ( )
- โencodeURI() menyandikan URL lengkap sekaligus mempertahankan karakter struktural (/ ? # & = :) โ jangan pernah gunakan untuk nilai individual
- โURLSearchParams menyandikan pasangan kunci-nilai secara otomatis menggunakan format application/x-www-form-urlencoded, di mana spasi menjadi + bukan %20
- โDouble-encoding adalah bug produksi yang paling umum: encodeURIComponent(encodeURIComponent(value)) mengubah %20 menjadi %2520
- โLibrary qs menangani objek bertingkat dan array dalam query string secara native โ URLSearchParams standar tidak mendukungnya
Apa itu URL Encoding?
URL encoding (secara resmi disebut percent-encoding, didefinisikan dalam RFC 3986) mengubah karakter yang tidak diizinkan atau memiliki arti khusus dalam URL menjadi representasi yang aman. Setiap byte yang tidak aman digantikan dengan tanda persen diikuti dua digit heksadesimal โ kode ASCII karakter tersebut. Spasi menjadi %20, ampersand menjadi %26, garis miring menjadi %2F.
Karakter yang selalu aman dan tidak pernah disandikan disebut karakter tak-terreservasi: huruf AโZ dan aโz, angka 0โ9, dan empat simbol - _ . ~. Semua yang lain harus disandikan saat digunakan sebagai data, atau memiliki peran struktural dalam URL itu sendiri (seperti / yang memisahkan segmen jalur atau &yang memisahkan parameter query). Konsekuensi praktisnya: nama produk seperti โKeyboard & Mouse Nirkabelโ dalam parameter query akan merusak struktur URL jika diteruskan mentah-mentah.
https://shop.example.com/search?q=Wireless Keyboard & Mouse&category=peripherals
https://shop.example.com/search?q=Wireless%20Keyboard%20%26%20Mouse&category=peripherals
encodeURIComponent() โ Fungsi yang Tepat untuk Parameter Query
encodeURIComponent() adalah tulang punggung URL encoding di JavaScript. Fungsi ini menyandikan setiap karakter kecuali set tak-terreservasi (AโZ, aโz, 0โ9, - _ . ! ~ * ' ( )). Yang terpenting, fungsi ini menyandikan semua karakter yang memiliki arti struktural dalam URL โ &, =, ?, #, / โ sehingga aman digunakan dalam nilai parameter. Tidak perlu impor; fungsi ini adalah fungsi global yang tersedia di semua lingkungan JavaScript.
Contoh minimal yang berfungsi
// Encode a search query parameter that contains special characters
const searchQuery = 'Wireless Keyboard & Mouse'
const filterStatus = 'in-stock'
const maxPrice = '149.99'
const searchUrl = `https://shop.example.com/products?` +
`q=${encodeURIComponent(searchQuery)}` +
`&status=${encodeURIComponent(filterStatus)}` +
`&maxPrice=${encodeURIComponent(maxPrice)}`
console.log(searchUrl)
// https://shop.example.com/products?q=Wireless%20Keyboard%20%26%20Mouse&status=in-stock&maxPrice=149.99Menyandikan URL redirect sebagai parameter query
// The redirect destination is itself a URL โ it must be fully encoded
// or the outer URL parser will misinterpret its ? and & as its own
const redirectAfterLogin = 'https://dashboard.internal/reports?view=weekly&team=platform'
const loginUrl = `https://auth.company.com/login?next=${encodeURIComponent(redirectAfterLogin)}`
console.log(loginUrl)
// https://auth.company.com/login?next=https%3A%2F%2Fdashboard.internal%2Freports%3Fview%3Dweekly%26team%3Dplatform
// Decoding on the receiving end
const params = new URLSearchParams(window.location.search)
const next = params.get('next') // Automatically decoded
const nextUrl = new URL(next!) // Safe to parse
console.log(nextUrl.hostname) // dashboard.internalMenyandikan karakter non-ASCII dan Unicode
// encodeURIComponent handles Unicode natively in all modern environments
// Each UTF-8 byte of the character is percent-encoded
const customerName = 'Santoso, Budi'
const productTitle = 'ๆฑไบฌ wireless adapter'
const reviewText = 'Sangat bagus โ berfungsi sempurna'
console.log(encodeURIComponent(customerName))
// Santoso%2C%20Budi
console.log(encodeURIComponent(productTitle))
// %E6%9D%B1%E4%BA%AC%20wireless%20adapter
console.log(encodeURIComponent(reviewText))
// Sangat%20bagus%20%E2%80%94%20berfungsi%20sempurna
// Decoding back
console.log(decodeURIComponent('Santoso%2C%20Budi'))
// Santoso, BudiencodeURIComponent() menggunakan pengkodean string UTF-16 internal mesin JavaScript, lalu menyandikan setiap byte UTF-8 karakter secara terpisah. Karakter seperti รผ (U+00FC) disandikan menjadi %C3%BC karena representasi UTF-8-nya adalah dua byte: 0xC3 dan 0xBC. Ini benar dan mengikuti standar URI โ server diharapkan mendekode urutan byte UTF-8 kembali ke codepoint aslinya.Fungsi URL Encoding JavaScript โ Referensi Karakter
Ketiga pendekatan penyandian native berbeda dalam karakter mana yang disandikan. Tabel di bawah menunjukkan output untuk karakter yang paling sering bermasalah:
| Karakter | Peran dalam URL | encodeURIComponent() | encodeURI() | URLSearchParams |
|---|---|---|---|---|
| Spasi | pemisah kata | %20 | %20 | + |
| & | pemisah parameter | %26 | dipertahankan | %26 |
| = | kunci=nilai | %3D | dipertahankan | %3D |
| + | spasi tersandikan (form) | %2B | %2B | %2B |
| ? | awal query | %3F | dipertahankan | %3F |
| # | fragmen | %23 | dipertahankan | %23 |
| / | pemisah jalur | %2F | dipertahankan | %2F |
| : | skema / port | %3A | dipertahankan | %3A |
| @ | pemisah auth | %40 | dipertahankan | %40 |
| % | persen literal | %25 | %25 | %25 |
| ~ | tak-terreservasi | dipertahankan | dipertahankan | dipertahankan |
Kolom yang kritis adalah encodeURIComponent() vs encodeURI() untuk & dan =: encodeURI() membiarkannya tidak berubah, yang benar saat menyandikan URL lengkap tetapi berbahaya saat menyandikan nilai yang mengandung karakter-karakter ini.
encodeURI() โ Kapan Mempertahankan Struktur URL
encodeURI() dirancang untuk menyandikan URL lengkapโ fungsi ini mempertahankan semua karakter yang merupakan bagian struktural valid dari URI: skema (https://), host, pemisah jalur, pembatas query, dan pengenal fragmen. Gunakan ketika Anda menerima URL yang mungkin mengandung spasi atau karakter non-ASCII di segmen jalurnya, tetapi Anda perlu mempertahankan strukturnya tetap utuh.
Membersihkan URL yang diberikan pengguna
// A URL pasted from a document with spaces in the path and non-ASCII chars const rawUrl = 'https://cdn.example.com/assets/product images/Mรผnchen chair.png' const safeUrl = encodeURI(rawUrl) console.log(safeUrl) // https://cdn.example.com/assets/product%20images/M%C3%BCnchen%20chair.png // encodeURIComponent would break it โ it encodes the :// and all / characters const broken = encodeURIComponent(rawUrl) console.log(broken) // https%3A%2F%2Fcdn.example.com%2Fassets%2Fproduct%20images%2FM%C3%BCnchen%20chair.png // โ Not a valid URL โ the scheme and slashes are destroyed
URL biasanya pilihan yang lebih baik daripada encodeURI() untuk menangani string URL yang diberikan pengguna โ fungsi ini menormalkan URL, memvalidasi struktur, dan memberi Anda API yang bersih untuk mengakses setiap komponen. Gunakan encodeURI() hanya untuk kasus di mana Anda membutuhkan hasil string dan sudah tahu bahwa inputnya secara struktural adalah URL yang valid.URLSearchParams โ Pendekatan Modern untuk Query String
URLSearchParams adalah cara idiomatis untuk membangun dan mengurai query string di JavaScript modern. Tersedia secara global di semua browser modern dan Node.js 10+, dan menangani penyandian secara otomatis โ Anda bekerja dengan pasangan kunci-nilai biasa dan menghasilkan output yang benar. Satu detail penting: fungsi ini mengikuti spesifikasi application/x-www-form-urlencoded, yang menyandikan spasi sebagai + bukan %20. Ini benar dan didukung secara luas, tetapi Anda harus menyadarinya ketika server Anda mengharapkan format tertentu.
Membangun URL permintaan pencarian
// Building a search API URL with multiple parameters
const filters = {
query: 'standing desk',
category: 'office-furniture',
minPrice: '200',
maxPrice: '800',
inStock: 'true',
sortBy: 'price_asc',
}
const params = new URLSearchParams(filters)
const apiUrl = `https://api.example.com/v2/products?${params}`
console.log(apiUrl)
// https://api.example.com/v2/products?query=standing+desk&category=office-furniture&minPrice=200&maxPrice=800&inStock=true&sortBy=price_asc
// Appending additional params after construction
params.append('page', '2')
params.append('tag', 'ergonomic & adjustable')
console.log(params.toString())
// query=standing+desk&...&tag=ergonomic+%26+adjustableMengurai query string yang masuk
// Both browser (window.location.search) and Node.js (req.url) scenarios
function parseWebhookCallbackUrl(rawSearch: string) {
const params = new URLSearchParams(rawSearch)
return {
eventId: params.get('event_id'), // null if missing
timestamp: Number(params.get('ts')),
signature: params.get('sig'),
redirectUrl: params.get('redirect'), // Automatically decoded
tags: params.getAll('tag'), // Handles repeated keys
}
}
const callbackQuery = '?event_id=evt_9c2f&ts=1717200000&sig=sha256%3Dabc123&redirect=https%3A%2F%2Fdashboard.internal%2F&tag=payment&tag=webhook'
const parsed = parseWebhookCallbackUrl(callbackQuery)
console.log(parsed.redirectUrl) // https://dashboard.internal/
console.log(parsed.tags) // ['payment', 'webhook']Cara Menyandikan Parameter URL dalam Permintaan Fetch JavaScript
Tempat paling umum URL encoding muncul dalam kode produksi adalah di dalam panggilan fetch() โ baik membangun URL permintaan atau mengirim data formulir dalam isi permintaan. Setiap skenario memiliki pendekatan yang benar tersendiri.
Permintaan GET โ menyandikan parameter query
async function searchInventory(params: {
sku?: string
warehouse: string
minStock: number
updatedAfter?: Date
}): Promise<{ items: unknown[]; total: number }> {
const searchParams = new URLSearchParams()
if (params.sku) searchParams.set('sku', params.sku)
searchParams.set('warehouse', params.warehouse)
searchParams.set('min_stock', String(params.minStock))
if (params.updatedAfter) searchParams.set('updated_after', params.updatedAfter.toISOString())
const url = `https://inventory.internal/api/items?${searchParams}`
const res = await fetch(url, {
headers: {
'Authorization': `Bearer ${process.env.INVENTORY_API_KEY}`,
'Accept': 'application/json',
},
})
if (!res.ok) {
throw new Error(`Inventory API ${res.status}: ${await res.text()}`)
}
return res.json()
}
const results = await searchInventory({
warehouse: 'eu-west-1',
minStock: 10,
updatedAfter: new Date('2025-01-01'),
})
console.log(`Found ${results.total} items`)Permintaan POST โ menyandikan URL isi formulir
// application/x-www-form-urlencoded POST โ used by OAuth token endpoints,
// legacy form-submission APIs, and some webhook providers
async function requestOAuthToken(
clientId: string,
clientSecret: string,
code: string,
redirectUri: string,
): Promise<{ access_token: string; expires_in: number }> {
const body = new URLSearchParams({
grant_type: 'authorization_code',
client_id: clientId,
client_secret: clientSecret,
code,
redirect_uri: redirectUri, // URLSearchParams encodes this automatically
})
const res = await fetch('https://oauth.provider.com/token', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: body.toString(),
// body: body โ also works directly in modern environments (Fetch spec accepts URLSearchParams)
})
if (!res.ok) {
const err = await res.json()
throw new Error(`OAuth error: ${err.error_description ?? err.error}`)
}
return res.json()
}Saat Anda perlu menguji atau men-debug URL yang telah disandikan tanpa menyiapkan skrip, tempel nilai mentah langsung ke Encoder URL โ fungsi ini menyandikan dan mendekode secara instan, menunjukkan dengan tepat apa yang akan dilihat browser dan server. Berguna untuk memeriksa URI redirect OAuth, URL callback webhook, dan parameter permintaan bertanda tangan CDN.
URL Encoding Baris Perintah dengan Node.js dan Shell
Untuk skrip shell, pipeline CI, atau debugging cepat, beberapa pendekatan baris perintah bekerja tanpa menulis skrip lengkap.
# โโ Node.js one-liners โ cross-platform (macOS, Linux, Windows) โโโโโโโโ
# encodeURIComponent โ encode a single value
node -e "console.log(encodeURIComponent(process.argv[1]))" "Wireless Keyboard & Mouse"
# Wireless%20Keyboard%20%26%20Mouse
# Build a complete query string
node -e "console.log(new URLSearchParams(JSON.parse(process.argv[1])).toString())" '{"q":"standing desk","category":"office-furniture","page":"1"}'
# q=standing+desk&category=office-furniture&page=1
# Decode a percent-encoded string
node -e "console.log(decodeURIComponent(process.argv[1]))" "Wireless%20Keyboard%20%26%20Mouse"
# Wireless Keyboard & Mouse
# โโ curl โ automatic encoding โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
# curl --data-urlencode encodes values automatically in GET and POST
curl -G "https://api.example.com/search" --data-urlencode "q=Wireless Keyboard & Mouse" --data-urlencode "category=office furniture"
# โโ Python one-liner (available on most systems) โโโโโโโโโโโโโโโโโโโโโโโโโ
python3 -c "from urllib.parse import quote; print(quote(input(), safe=''))"
# (type the string and press Enter)
# โโ jq + bash: encode every value in a JSON object โโโโโโโโโโโโโโโโโโโโโโโ
echo '{"q":"hello world","tag":"node & express"}' | node -e "const d=JSON.parse(require('fs').readFileSync('/dev/stdin','utf8')); console.log(new URLSearchParams(d).toString())"
# q=hello+world&tag=node+%26+expressAlternatif Berkinerja Tinggi: qs
URLSearchParams bawaan tidak mendukung objek bertingkat atau array โ bentuk query string yang digunakan oleh banyak API dan framework. Library qs (30 juta+ unduhan npm mingguan) menangani seluruh rentang pola query string yang digunakan di lapangan: objek bertingkat dengan notasi kurung siku (filters[status]=active), kunci berulang, enkoder kustom, dan format serialisasi array yang dapat dikonfigurasi.
npm install qs # or pnpm add qs
import qs from 'qs'
// URLSearchParams cannot represent this structure natively
const reportFilters = {
dateRange: {
from: '2025-01-01',
to: '2025-03-31',
},
status: ['published', 'archived'],
author: { id: 'usr_4f2a9c1b', role: 'editor' },
workspace: 'ws-platform-eu',
}
// qs produces bracket-notation query strings used by Express, Rails, Django REST
const query = qs.stringify(reportFilters, { encode: true })
console.log(query)
// dateRange%5Bfrom%5D=2025-01-01&dateRange%5Bto%5D=2025-03-31&status%5B0%5D=published&status%5B1%5D=archived&author%5Bid%5D=usr_4f2a9c1b&author%5Brole%5D=editor&workspace=ws-platform-eu
// Human-readable (no encoding) โ useful for debugging
console.log(qs.stringify(reportFilters, { encode: false }))
// dateRange[from]=2025-01-01&dateRange[to]=2025-03-31&status[0]=published&status[1]=archived...
// Parsing back
const parsed = qs.parse(query)
console.log(parsed.dateRange) // { from: '2025-01-01', to: '2025-03-31' }
console.log(parsed.status) // ['published', 'archived']Untuk parameter kunci-nilai datar, URLSearchParams selalu menjadi pilihan tepat โ sudah bawaan, tidak ada overhead, dan didukung secara universal. Gunakan qs hanya ketika Anda membutuhkan struktur bertingkat, format serialisasi array selain kunci berulang, atau Anda mengintegrasikan dengan framework back-end yang mengharapkan query string bernotasi kurung siku.
Kesalahan Umum
Saya telah melihat empat kesalahan ini berulang kali dalam basis kode produksi โ sebagian besar adalah kegagalan diam-diam yang hanya muncul ketika nilai mengandung karakter khusus, yang persis jenis bug yang lolos dari pengujian unit dan hanya muncul dengan data pengguna nyata.
Kesalahan 1 โ Menggunakan encodeURI() untuk nilai parameter query
Masalah: encodeURI() tidak menyandikan &, =, atau +. Ketika nilai mengandung karakter-karakter ini, karakter tersebut diinterpretasikan sebagai sintaks query string, secara diam-diam memisahkan atau menimpa parameter. Perbaikan: selalu gunakan encodeURIComponent() untuk nilai individual.
// โ encodeURI does not encode & and = in the value
// "plan=pro&promo=SAVE20" is treated as two separate params
const planName = 'Pro Plan (save=20% & free trial)'
const url = `/checkout?plan=${encodeURI(planName)}`
// /checkout?plan=Pro%20Plan%20(save=20%%20&%20free%20trial)
// โ & breaks the query string// โ
encodeURIComponent encodes & and = safely
const planName = 'Pro Plan (save=20% & free trial)'
const url = `/checkout?plan=${encodeURIComponent(planName)}`
// /checkout?plan=Pro%20Plan%20(save%3D20%25%20%26%20free%20trial)
// โ = and & are both encodedKesalahan 2 โ Double-encoding string yang sudah tersandikan
Masalah: Memanggil encodeURIComponent() pada nilai yang sudah disandikan dengan persen mengubah % menjadi %25, sehingga %20 menjadi %2520. Server mendekode sekali dan menerima literal %20 bukan spasi. Perbaikan: dekode dulu, lalu encode ulang, atau pastikan nilai tidak pernah disandikan dua kali.
// โ encodedParam already contains %20 โ encoding again produces %2520
const encodedParam = 'Berlin%20Office'
const url = `/api/locations/${encodeURIComponent(encodedParam)}`
// /api/locations/Berlin%2520Office
// Server sees: "Berlin%20Office" (a literal percent-twenty, not a space)// โ
Decode first if the value may already be encoded
const maybeEncoded = 'Berlin%20Office'
const clean = decodeURIComponent(maybeEncoded) // 'Berlin Office'
const url = `/api/locations/${encodeURIComponent(clean)}`
// /api/locations/Berlin%20Office โ correctKesalahan 3 โ Tidak memperhitungkan perbedaan + / %20 antara URLSearchParams dan encodeURIComponent
Masalah: URLSearchParams menyandikan spasi sebagai + (application/x-www-form-urlencoded), sementara encodeURIComponent() menggunakan %20. Mencampur keduanya dalam URL yang sama โ misalnya, menambahkan string yang sudah disandikan ke output URLSearchParams โ menghasilkan penyandian yang tidak konsisten dan membingungkan beberapa parser. Perbaikan: pilih satu pendekatan dan gunakan secara konsisten di seluruh fungsi pembuatan URL.
// โ Mixed: URLSearchParams uses + for spaces, but we're appending
// a manually-encoded segment that uses %20
const base = new URLSearchParams({ category: 'office furniture' })
const extra = `sort=${encodeURIComponent('price asc')}`
const url = `/api/products?${base}&${extra}`
// /api/products?category=office+furniture&sort=price%20asc
// โ two different space encodings in the same URL// โ
Use URLSearchParams exclusively โ consistent encoding throughout
const params = new URLSearchParams({
category: 'office furniture',
sort: 'price asc',
})
const url = `/api/products?${params}`
// /api/products?category=office+furniture&sort=price+ascKesalahan 4 โ Lupa menyandikan segmen jalur yang mengandung garis miring
Masalah: Pengenal sumber daya seperti jalur file (reports/2025/q1.pdf) yang digunakan sebagai segmen jalur REST mengandung karakter / yang diinterpretasikan oleh router server sebagai pemisah jalur, mengarahkan ke endpoint yang tidak ada. Perbaikan: selalu gunakan encodeURIComponent() untuk segmen jalur yang mungkin mengandung garis miring.
// โ The file path contains / โ the server receives a 3-segment path
// instead of a single resource ID
const filePath = 'reports/2025/q1-financials.pdf'
const url = `https://storage.example.com/objects/${filePath}`
// https://storage.example.com/objects/reports/2025/q1-financials.pdf
// โ Server routes to /objects/:year/:filename โ 404 or wrong resource// โ
encodeURIComponent encodes / as %2F โ single path segment
const filePath = 'reports/2025/q1-financials.pdf'
const url = `https://storage.example.com/objects/${encodeURIComponent(filePath)}`
// https://storage.example.com/objects/reports%2F2025%2Fq1-financials.pdf
// โ Server receives the full file path as one resource identifierMetode URL Encoding JavaScript โ Perbandingan Cepat
| Metode | Menyandikan spasi sebagai | Menyandikan & = ? | Menyandikan # / : | Kasus penggunaan | Perlu instalasi |
|---|---|---|---|---|---|
| encodeURIComponent() | %20 | โ ya | โ ya | Menyandikan nilai parameter individual | No |
| encodeURI() | %20 | โ tidak | โ tidak | Membersihkan string URL lengkap | No |
| URLSearchParams | + | โ ya | โ ya | Membangun dan mengurai query string | No |
| Konstruktor URL | otomatis per komponen | otomatis | otomatis | Menyusun dan menormalkan URL lengkap | No |
| Library qs | %20 (dapat dikonfigurasi) | โ ya | โ ya | Objek bertingkat dan array dalam query string | npm install qs |
Untuk sebagian besar kasus, pilihan menyederhanakan menjadi tiga skenario. Gunakan URLSearchParams saat membangun query string multi-parameter dari data terstruktur โ ini adalah opsi paling aman dan paling mudah dibaca. Gunakan encodeURIComponent() untuk menyandikan nilai tunggal dalam URL template literal, untuk segmen jalur, atau untuk nilai dalam sistem yang mengharapkan %20 bukan + untuk spasi (seperti AWS S3 signed URL). Gunakan qs hanya ketika query string Anda membawa objek bertingkat atau array yang tidak dapat direpresentasikan URLSearchParams secara native.
Pertanyaan yang Sering Diajukan
Alat Terkait
Untuk encode atau decode sekali klik tanpa menulis kode apa pun, tempel string Anda langsung ke Encoder URL โ fungsi ini menangani percent-encoding dan decoding secara instan di browser Anda, dengan output yang sudah disandikan siap untuk disalin ke panggilan fetch atau terminal.
Alex is a front-end and Node.js developer with extensive experience building web applications and developer tooling. He is passionate about web standards, browser APIs, and the JavaScript ecosystem. In his spare time he contributes to open-source projects and writes about modern JavaScript patterns, performance optimisation, and everything related to the web platform.
Sophie is a full-stack developer focused on TypeScript across the entire stack โ from React frontends to Express and Fastify backends. She has a particular interest in type-safe API design, runtime validation, and the patterns that make large JavaScript codebases stay manageable. She writes about TypeScript idioms, Node.js internals, and the ever-evolving JavaScript module ecosystem.