Pyodide: Python Sungguhan di Browser via WebAssembly
Pyodide mengompilasi CPython ke WebAssembly agar Python dengan NumPy dan pandas jalan langsung di browser. Cara kerja dan kapan layak dipakai.

Python di browser sudah jadi impian sejak awal 2010-an, dan setiap percobaan selalu menghadapi masalah yang sama: Python terlalu terikat pada runtime C milik CPython untuk bisa di-port dengan mudah ke lingkungan web. Transcrypt, Brython, dan Skulpt mencoba mengatasinya dengan mengimplementasikan ulang Python dalam JavaScript. Cara ini cukup untuk skrip sederhana, tapi langsung runtuh begitu Anda butuh NumPy, pandas, atau library ekstensi C lainnya yang membuat Python benar-benar berguna.
Pyodide mengambil pendekatan berbeda: kompilasi interpreter CPython asli ke WebAssembly. Ini bukan implementasi ulang, melainkan source code CPython yang sebenarnya, dikompilasi dengan Emscripten supaya bisa jalan di browser. Artinya kompatibilitas bahasanya penuh, termasuk ekstensi C. Anda bisa import numpy dan itu langsung jalan, karena binary Wasm yang sudah dikompilasi memuat kode C NumPy yang sebenarnya.
Cara Kerja Pyodide di Balik Layar
Proses build Pyodide mengambil source tree CPython lalu mengompilasinya dengan Emscripten, toolchain compiler yang menargetkan WebAssembly alih-alih kode mesin native. Hasilnya berupa binary .wasm yang berisi interpreter Python, ditambah kode glue JavaScript yang menghubungkannya ke lingkungan browser.
Bagian yang rumit adalah ekstensi C-nya. NumPy, misalnya, memuat lebih dari 100.000 baris kode C dan Fortran. Pyodide sudah mengompilasi sejumlah package populer di muka — NumPy, pandas, scikit-learn, matplotlib, scipy — menjadi modul Wasm yang bisa dimuat sesuai kebutuhan. Saat Anda memanggil import numpy, Pyodide mengunduh modul Wasm NumPy yang sudah dikompilasi, menautkannya ke interpreter yang sedang berjalan, lalu menginisialisasinya.
<!-- Minimal Pyodide example -->
<script src="https://cdn.jsdelivr.net/pyodide/v0.27.0/full/pyodide.js"></script>
<script>
async function main() {
// Load the Python interpreter (~10MB download)
const pyodide = await loadPyodide();
// Run Python code directly
pyodide.runPython(`
import sys
print(f"Python {sys.version} running in the browser!")
`);
// Load packages on demand
await pyodide.loadPackage('numpy');
// Use NumPy — the real NumPy, compiled to Wasm
const result = pyodide.runPython(`
import numpy as np
arr = np.random.randn(1000)
f"Mean: {arr.mean():.4f}, Std: {arr.std():.4f}"
`);
console.log(result); // "Mean: 0.0123, Std: 1.0045"
}
main();
</script>
Jembatan JavaScript-Python
Salah satu fitur terbaik Pyodide adalah interop Python dan JavaScript yang mulus. Objek Python otomatis di-proxy ke JavaScript dan sebaliknya. Anda bisa memanggil fungsi JavaScript dari Python, memanipulasi DOM dari Python, dan mengirim data antar kedua bahasa tanpa serialisasi manual.
// JavaScript calling Python
const pyodide = await loadPyodide();
// Define a Python function
pyodide.runPython(`
def analyze(data):
import statistics
return {
'mean': statistics.mean(data),
'median': statistics.median(data),
'stdev': statistics.stdev(data)
}
`);
// Call it from JavaScript with JS data
const analyze = pyodide.globals.get('analyze');
const result = analyze([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
console.log(result.toJs()); // {mean: 5.5, median: 5.5, stdev: 3.03}
// Python accessing the DOM
pyodide.runPython(`
from js import document
element = document.getElementById('output')
element.textContent = 'Updated from Python!'
`);
Sistem proxy menangani konversi tipe secara otomatis: dict Python menjadi objek JavaScript, list Python menjadi array JavaScript, dan angka Python menjadi angka JavaScript. Untuk transfer data besar — misalnya mengirim array NumPy berisi satu juta elemen ke library visualisasi JavaScript — Pyodide memakai shared memory buffer agar tidak perlu menyalin data, dan ini krusial untuk performa.
Kapan Pyodide Masuk Akal
Lingkungan komputasi interaktif. JupyterLite, yang dibangun di atas Pyodide, menjalankan notebook Jupyter sepenuhnya di browser. Tidak perlu server — kernel Python berjalan lokal di Wasm. Ini mengubah banyak hal di dunia pendidikan: mahasiswa bisa menjalankan notebook Python tanpa menginstal apa pun, dan dosen tidak perlu menyiapkan server.
Alat eksplorasi data. Aplikasi web yang memungkinkan pengguna mengunggah data dan menganalisisnya bisa memakai Pyodide untuk memproses data sepenuhnya di sisi klien. Tidak ada data yang keluar dari browser, jadi isu privasi teratasi dan biaya server hilang. Uploader CSV yang menjalankan transformasi pandas di browser jauh lebih mudah di-deploy dan lebih privat dibanding yang mengirim data ke backend.
Dokumentasi dengan contoh langsung. Dokumentasi library Python bisa menyertakan blok kode interaktif yang benar-benar dijalankan. Alih-alih menampilkan output statis, pembaca bisa mengubah kode dan langsung melihat hasilnya. Untuk belajar, ini jauh lebih efektif dibanding contoh statis.
Prototyping dan eksperimen. Data scientist yang berpikir dalam Python bisa membuat prototipe transformasi dan visualisasi data langsung di browser, lalu membagikan hasilnya lewat URL. Tanpa setup environment, tanpa ribet mengatur dependency, dan tanpa drama 'sudah jalan di mesin saya'.
Realitas Performanya
Pyodide memang tidak cepat. WebAssembly punya overhead dibanding kode native, biasanya 1,5–3 kali lebih lambat untuk pekerjaan yang berat secara komputasi. Di atas itu, Pyodide menjalankan CPython (yang sudah 100 kali lebih lambat dari C untuk kode Python murni) yang dikompilasi ke Wasm. Untuk loop Python murni, Pyodide kira-kira 2–5 kali lebih lambat dibanding CPython native.
Tapi begini: beban kerja yang cocok untuk Pyodide biasanya didominasi pemanggilan ekstensi C, bukan Python murni. Saat Anda memanggil np.dot(a, b), komputasi sebenarnya dilakukan oleh kode C yang sudah dikompilasi (sekarang dikompilasi ke Wasm). Overhead Wasm pada kode C itu 1,5–3 kali, dan untuk kasus pemakaian interaktif, itu masih sangat wajar. Perkalian matriks NumPy yang natively butuh 10 ms bisa menjadi 20 ms di Pyodide. Untuk pengguna yang mengklik 'Run' di notebook, selisih itu tidak terasa.
Performance comparison (approximate):
Native CPython Pyodide (Wasm)
Pure Python loop: 1x 3-5x slower
NumPy operations: 1x 1.5-3x slower
Pandas groupby: 1x 2-3x slower
Startup time: 50ms 2-5 seconds
Package loading: instant (pip) 2-10s (download + init)
Startup is the real cost. Once loaded, interactive
performance is adequate for most use cases.
Biaya startup justru masalah yang lebih besar. Runtime inti Pyodide berukuran unduhan 10 MB. Memuat NumPy menambah 7 MB, dan pandas menambah 10 MB lagi. Untuk halaman web yang harus tampil cepat, delay inisialisasi 5 detik adalah pemutus kesepakatan. Itu sebabnya Pyodide paling pas untuk aplikasi yang memang diharapkan pengguna menunggu environment termuat — notebook, alat data, tutorial interaktif — bukan halaman web tradisional.
Yang Tidak Bisa Dilakukan Pyodide
Tidak semua package Python bisa jalan di Pyodide. Package yang punya dependency sistem — driver database, library GUI, apa pun yang memanggil API spesifik OS — tidak akan terkompilasi ke Wasm. psycopg2 membutuhkan library client PostgreSQL. opencv membutuhkan library grafis sistem. Dependency semacam itu tidak ada di lingkungan browser.
Networking juga terbatas. Modul socket Python tidak berfungsi di browser — tidak ada akses socket mentah dari Wasm. Permintaan HTTP lewat API fetch() browser melalui jembatan JavaScript Pyodide, sehingga tunduk pada pembatasan CORS. Anda tidak bisa menjalankan server Flask di Pyodide (tidak ada socket untuk listen), dan Anda tidak bisa membuat koneksi jaringan sembarangan.
Threading didukung sebagian lewat Web Worker, tapi GIL (Global Interpreter Lock) Python tetap berlaku, dan model threading-nya berbeda dari CPython native. Untuk paralelisme yang terikat CPU, multiprocessing (tiap worker mendapat instance Wasm sendiri) lebih baik dibanding threads.
Pyodide vs Python Hasil Transpile
Layak membandingkan pendekatan Pyodide (mengompilasi CPython ke Wasm) dengan alternatifnya (mentranspile Python ke JavaScript). Proyek seperti Transcrypt dan Brython mengubah sintaks Python menjadi JavaScript, sehingga kodenya berjalan native di engine JS browser.
Transpilasi lebih cepat saat runtime — kode JavaScript yang dihasilkan berjalan dengan kecepatan JS native, bukan kecepatan CPython di Wasm. Tidak ada biaya startup sama sekali (tidak ada runtime yang perlu diunduh). Tapi konsekuensinya, kompatibilitasnya berkurang: Python hasil transpile tidak bisa menjalankan ekstensi C, punya perbedaan semantik halus dibanding CPython (terutama soal tipe numerik, penanganan string, dan kasus-kasus pinggiran), dan hanya mendukung sebagian standard library.
Keunggulan Pyodide adalah menjalankan CPython yang sebenarnya. Kalau kode Python Anda jalan di CPython, ia akan jalan di Pyodide (kecuali dependency tingkat sistem). Untuk alur kerja data science yang bergantung pada NumPy, pandas, dan scikit-learn, kompatibilitas ini wajib. Untuk skrip sederhana yang tidak butuh ekstensi C, transpilasi mungkin pilihan yang lebih baik — seperti pada perbandingan Wasm vs. JS native lainnya, alat yang tepat bergantung pada beban kerjanya.
Ke Mana Arahnya
Pyodide masih aktif dikembangkan dan terus membaik. Versi-versi terbaru berhasil memperkecil ukuran runtime inti, mempercepat startup dengan streaming compilation (browser mengompilasi Wasm sambil mengunduhnya), dan memperluas daftar package yang sudah dikompilasi. Ekosistem WebAssembly juga makin matang — WASI menyediakan antarmuka sistem yang terstandar, dan component model akan membuat interop antar modul Wasm lebih baik.
Tren yang lebih besar adalah browser makin menjadi runtime universal. Lewat JavaScript, Wasm, dan proyek seperti Pyodide, Anda bisa menjalankan kode dari hampir semua bahasa langsung di browser. Ini tidak menggantikan komputasi server-side — justru melengkapinya dengan memindahkan komputasi yang tidak butuh server ke sisi klien. Untuk ekosistem data science Python yang sangat besar, menjalankan kode di sisi klien membuka kasus pemakaian yang dulu tidak mungkin.


