URL Encode JavaScript — encodeURIComponent()
Użyj darmowego Koder URL Online bezpośrednio w przeglądarce — bez instalacji.
Wypróbuj Koder URL Online online →Kiedy budujesz URL wyszukiwania, przekazujesz ścieżkę przekierowania jako parametr zapytania lub tworzysz żądanie autoryzacji OAuth, znaki specjalne takie jak &, = i spacje po cichu uszkodzą URL, jeśli wcześniej nie wykonasz kodowania URL. JavaScript oferuje trzy wbudowane podejścia — encodeURIComponent(), encodeURI() oraz URLSearchParams — każde zaprojektowane dla innego przypadku użycia, a wybranie złego jest główną przyczyną większości błędów kodowania, które napotkałem podczas przeglądów kodu. Do szybkiego jednorazowego kodowania bez pisania kodu, Koder URL ToolDeck obsługuje to natychmiastowo w przeglądarce. Ten przewodnik szczegółowo omawia wszystkie trzy podejścia (JavaScript ES2015+ / Node.js 10+): kiedy używać każdego, jak różnią się w obsłudze spacji i znaków zarezerwowanych, wzorce Fetch i API z prawdziwego świata, użycie CLI oraz cztery błędy powodujące najbardziej subtelne błędy produkcyjne.
- ✓encodeURIComponent() to właściwy wybór do kodowania wartości poszczególnych parametrów — koduje każdy znak z wyjątkiem A–Z, a–z, 0–9 oraz - _ . ! ~ * ' ( )
- ✓encodeURI() koduje kompletny URL, zachowując znaki strukturalne (/ ? # & = :) — nigdy nie używaj go dla pojedynczych wartości
- ✓URLSearchParams automatycznie koduje pary klucz-wartość w formacie application/x-www-form-urlencoded, gdzie spacje stają się + zamiast %20
- ✓Podwójne kodowanie to najczęstszy błąd produkcyjny: encodeURIComponent(encodeURIComponent(value)) zamienia %20 w %2520
- ✓Biblioteka qs natywnie obsługuje zagnieżdżone obiekty i tablice w ciągach zapytania — standardowy URLSearchParams tego nie potrafi
Czym jest kodowanie URL?
Kodowanie URL (formalnie zwane kodowaniem procentowym, zdefiniowanym w RFC 3986) konwertuje znaki, które nie są dozwolone lub mają specjalne znaczenie w URL, na bezpieczną reprezentację. Każdy niebezpieczny bajt jest zastępowany znakiem procentu, po którym następują dwie cyfry szesnastkowe — kod ASCII znaku. Spacja staje się %20, ampersand staje się %26, ukośnik staje się %2F.
Znaki, które są zawsze bezpieczne i nigdy nie są kodowane, nazywają się znakami niezarezerwowanymi: litery A–Z i a–z, cyfry 0–9 oraz cztery symbole - _ . ~. Wszystko inne albo musi być zakodowane podczas używania jako dane, albo pełni strukturalną rolę w samym URL (np. / rozdziela segmenty ścieżki, a &rozdziela parametry zapytania). Praktyczna konsekwencja: nazwa produktu taka jak „Klawiatura bezprzewodowa & Mysz" w parametrze zapytania zniszczy strukturę URL, jeśli zostanie przekazana w surowej postaci.
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() — właściwa funkcja dla parametrów zapytania
encodeURIComponent() to główne narzędzie kodowania URL w JavaScript. Koduje każdy znak z wyjątkiem zestawu niezarezerwowanego (A–Z, a–z, 0–9, - _ . ! ~ * ' ( )). Co kluczowe, koduje wszystkie znaki mające strukturalne znaczenie w URL — &, =, ?, #, / — co czyni go bezpiecznym do użycia w wartościach parametrów. Nie jest wymagany import; jest to funkcja globalna dostępna we wszystkich środowiskach JavaScript.
Minimalny działający przykład
// 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.99Kodowanie URL przekierowania jako parametru zapytania
// 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.internalKodowanie znaków spoza ASCII i Unicode
// encodeURIComponent handles Unicode natively in all modern environments
// Each UTF-8 byte of the character is percent-encoded
const customerName = 'Kowalski, Tomasz'
const productTitle = 'Warszawa wireless adapter'
const reviewText = 'Bardzo dobry — działa idealnie'
console.log(encodeURIComponent(customerName))
// Kowalski%2C%20Tomasz
console.log(encodeURIComponent(productTitle))
// Warszawa%20wireless%20adapter
console.log(encodeURIComponent(reviewText))
// Bardzo%20dobry%20%E2%80%94%20dzia%C5%82a%20idealnie
// Decoding back
console.log(decodeURIComponent('Bardzo%20dobry%20%E2%80%94%20dzia%C5%82a%20idealnie'))
// Bardzo dobry — działa idealnieencodeURIComponent() używa wewnętrznego kodowania ciągów JavaScript UTF-16, a następnie koduje każdy bajt UTF-8 znaku oddzielnie. Znak ł (U+0142) koduje się do %C5%82, ponieważ jego reprezentacja UTF-8 składa się z dwóch bajtów: 0xC5 i 0x82. Jest to poprawne i zgodne ze standardem URI — serwery powinny dekodować sekwencję bajtów UTF-8 z powrotem do oryginalnego punktu kodowego.Funkcje kodowania URL w JavaScript — tabela znaków
Trzy natywne podejścia do kodowania różnią się dokładnie tym, które znaki kodują. Poniższa tabela pokazuje wynik dla najczęściej problematycznych znaków:
| Znak | Rola w URL | encodeURIComponent() | encodeURI() | URLSearchParams |
|---|---|---|---|---|
| Spacja | separator wyrazów | %20 | %20 | + |
| & | separator parametrów | %26 | zachowane | %26 |
| = | klucz=wartość | %3D | zachowane | %3D |
| + | zakodowana spacja (formularz) | %2B | %2B | %2B |
| ? | początek zapytania | %3F | zachowane | %3F |
| # | fragment | %23 | zachowane | %23 |
| / | separator ścieżki | %2F | zachowane | %2F |
| : | schemat / port | %3A | zachowane | %3A |
| @ | separator autoryzacji | %40 | zachowane | %40 |
| % | literał procentu | %25 | %25 | %25 |
| ~ | niezarezerwowany | zachowane | zachowane | zachowane |
Kluczowa kolumna to encodeURIComponent() vs encodeURI() dla & i =: encodeURI() pozostawia je niezmienione, co jest poprawne przy kodowaniu pełnego URL, ale katastrofalne przy kodowaniu wartości zawierającej te znaki.
encodeURI() — kiedy zachować strukturę URL
encodeURI() jest przeznaczony do kodowania kompletnego URL— zachowuje wszystkie znaki będące prawidłowymi strukturalnymi częściami URI: schemat (https://), host, separatory ścieżki, separatory zapytania i identyfikator fragmentu. Używaj go, gdy otrzymujesz URL, który może zawierać spacje lub znaki spoza ASCII w segmentach ścieżki, ale musisz zachować jego strukturę nietkniętą.
Czyszczenie URL dostarczonego przez użytkownika
// 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 jest zazwyczaj lepszym wyborem niż encodeURI() do obsługi ciągów URL dostarczonych przez użytkownika — normalizuje URL, waliduje strukturę i daje czysty interfejs API do dostępu do każdego komponentu. Zostaw encodeURI() dla przypadków, gdy potrzebujesz wyniku w postaci ciągu i już wiesz, że dane wejściowe są strukturalnie prawidłowym URL.URLSearchParams — nowoczesne podejście do ciągów zapytania
URLSearchParams to idiomatyczny sposób budowania i parsowania ciągów zapytania w nowoczesnym JavaScript. Jest dostępny globalnie we wszystkich nowoczesnych przeglądarkach i Node.js 10+, obsługuje kodowanie automatycznie — pracujesz ze zwykłymi parami klucz-wartość, a on produkuje poprawny wynik. Ważny szczegół: podąża za specyfikacją application/x-www-form-urlencoded, która koduje spacje jako + zamiast %20. Jest to poprawne i szeroko obsługiwane, ale powinieneś o tym pamiętać, gdy twój serwer oczekuje określonego formatu.
Budowanie URL żądania wyszukiwania
// 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+adjustableParsowanie przychodzącego ciągu zapytania
// 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']Jak kodować URL parametry w żądaniach JavaScript Fetch
Najczęstszym miejscem, w którym kodowanie URL pojawia się w kodzie produkcyjnym, są wywołania fetch() — albo podczas budowania URL żądania, albo podczas wysyłania danych formularza w treści żądania. Każdy scenariusz ma swoje własne poprawne podejście.
Żądanie GET — kodowanie parametrów zapytania
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`)Żądanie POST — kodowanie URL treści formularza
// 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()
}Gdy chcesz przetestować lub debugować zakodowany URL bez pisania skryptu, wklej surową wartość bezpośrednio do Kodera URL — koduje i dekoduje natychmiastowo, pokazując dokładnie to, co zobaczy przeglądarka i serwer. Przydatne do sprawdzania OAuth redirect URI, adresów URL wywołań zwrotnych webhooków i parametrów podpisanych żądań CDN.
Kodowanie URL w wierszu poleceń z Node.js i Shell
Do skryptów shell, potoków CI lub szybkiego debugowania istnieje kilka podejść wiersza poleceń działających bez pisania pełnego skryptu.
# ── 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+expressWydajna alternatywa: qs
Wbudowany URLSearchParams nie obsługuje zagnieżdżonych obiektów ani tablic — kształtu ciągów zapytania używanego przez wiele API i frameworków. Biblioteka qs (ponad 30M pobrań tygodniowo z npm) obsługuje pełen zakres wzorców ciągów zapytania stosowanych w praktyce: zagnieżdżone obiekty z notacją nawiasową (filters[status]=active), powtarzające się klucze, niestandardowe enkodery i konfigurowalne formaty serializacji tablic.
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']Dla płaskich parametrów klucz-wartość URLSearchParams jest zawsze właściwym wyborem — jest wbudowany, nie ma narzutu i jest powszechnie obsługiwany. Sięgaj po qs tylko wtedy, gdy potrzebujesz zagnieżdżonych struktur, formatów serializacji tablic innych niż powtarzające się klucze, lub integrujesz się z frameworkiem backendowym oczekującym ciągów zapytania w notacji nawiasowej.
Częste błędy
Wielokrotnie widziałem te cztery błędy w produkcyjnych bazach kodu — większość z nich to ciche awarie, które ujawniają się dopiero gdy wartość zawiera znak specjalny, co jest dokładnie tym rodzajem błędu, który przechodzi przez testy jednostkowe i pojawia się tylko przy prawdziwych danych użytkownika.
Błąd 1 — Użycie encodeURI() dla wartości parametrów zapytania
Problem: encodeURI() nie koduje &, = ani +. Gdy wartość zawiera te znaki, są one interpretowane jako składnia ciągu zapytania, po cichu dzieląc lub nadpisując parametry. Rozwiązanie: zawsze używaj encodeURIComponent() dla pojedynczych wartości.
// ❌ 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 encodedBłąd 2 — Podwójne kodowanie już zakodowanego ciągu
Problem: Wywołanie encodeURIComponent() na wartości, która jest już zakodowana procentowo, zamienia % w %25, więc %20 staje się %2520. Serwer dekoduje raz i otrzymuje literalne %20 zamiast spacji. Rozwiązanie: najpierw dekoduj, potem ponownie koduj, lub upewnij się, że wartość nigdy nie jest kodowana dwa razy.
// ❌ 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 — correctBłąd 3 — Ignorowanie różnicy między + i %20 w URLSearchParams i encodeURIComponent
Problem: URLSearchParams koduje spacje jako + (application/x-www-form-urlencoded), podczas gdy encodeURIComponent() używa %20. Mieszanie obu podejść w tym samym URL — na przykład dołączanie wstępnie zakodowanego ciągu do wyjścia URLSearchParams — produkuje niespójne kodowanie, które dezorientuje niektóre parsery. Rozwiązanie: wybierz jedno podejście i używaj go konsekwentnie w całej funkcji budującej 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+ascBłąd 4 — Zapomnienie o kodowaniu segmentów ścieżki zawierających ukośniki
Problem: Identyfikator zasobu taki jak ścieżka pliku (reports/2025/q1.pdf) użyty jako segment ścieżki REST zawiera znaki /, które router serwera interpretuje jako separatory ścieżki, kierując do nieistniejącego punktu końcowego. Rozwiązanie: zawsze używaj encodeURIComponent() dla segmentów ścieżki, które mogą zawierać ukośniki.
// ❌ 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 identifierMetody kodowania URL w JavaScript — szybkie porównanie
| Metoda | Koduje spacje jako | Koduje & = ? | Koduje # / : | Przypadek użycia | Wymaga instalacji |
|---|---|---|---|---|---|
| encodeURIComponent() | %20 | ✅ tak | ✅ tak | Kodowanie pojedynczych wartości parametrów | No |
| encodeURI() | %20 | ❌ nie | ❌ nie | Czyszczenie kompletnego ciągu URL | No |
| URLSearchParams | + | ✅ tak | ✅ tak | Budowanie i parsowanie ciągów zapytania | No |
| Konstruktor URL | auto wg komponentu | auto | auto | Konstruowanie i normalizacja pełnych URL | No |
| Biblioteka qs | %20 (konfigurowalne) | ✅ tak | ✅ tak | Zagnieżdżone obiekty i tablice w ciągach zapytania | npm install qs |
W zdecydowanej większości przypadków wybór sprowadza się do trzech scenariuszy. Używaj URLSearchParams przy budowaniu wieloparametrowych ciągów zapytania z danych strukturalnych — to najbezpieczniejsza i najbardziej czytelna opcja. Używaj encodeURIComponent() do kodowania pojedynczej wartości w szablonowym URL, dla segmentów ścieżki lub dla wartości w systemach oczekujących %20 zamiast + dla spacji (takich jak podpisane URL AWS S3). Sięgaj po qs tylko wtedy, gdy ciąg zapytania zawiera zagnieżdżone obiekty lub tablice, których URLSearchParams nie może reprezentować natywnie.
Często zadawane pytania
Powiązane narzędzia
Do jednorazowego kodowania lub dekodowania bez pisania kodu wklej swój ciąg bezpośrednio do Kodera URL — obsługuje kodowanie procentowe i dekodowanie natychmiastowo w przeglądarce, z zakodowanym wynikiem gotowym do skopiowania do wywołania fetch lub terminala.
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.