Loading Python environment…
Initializing Pyodide + NumPy + SymPy
Header shortcuts: 📦 Browse and 🧭 Tour appear when there is room for them, so a narrow screen may leave them out; ∑ Formula is off by default. Choose Always, When there is room, or Never for each under Appearance → Header shortcuts, and set which one gives up its place first. Formula appears for Python code and Markdown cells.
# Basic math
2 + 2
# NumPy
import numpy as np
np.linspace(0, 10, 5)
# Plotly chart (interactive)
x = np.linspace(0, 2*np.pi, 50)
plot(x, np.sin(x))
# Matplotlib (install once, then use)
%pip install matplotlib
import matplotlib.pyplot as plt
plt.plot([1, 4, 2, 3])
plt.title("Matplotlib")
plt.show()
# SymPy (LaTeX rendering)
from sympy import symbols, sqrt, solve
a, b, c, x = symbols('a b c x')
solve(a*x**2 + b*x + c, x)
# Suppress output with ;
big_array = np.arange(1000);
Install pure-Python packages from PyPI with %pip install:
%pip install requests
# Then use it
import requests
r = requests.get('https://api.github.com')
print(r.status_code)
Note: Only pure-Python packages are supported. Packages with C extensions (e.g. psutil) require pre-compiled WASM wheels.
Install R packages with install.packages() or %install:
# Standard R syntax (works out of the box)
install.packages("jsonlite")
library(jsonlite)
# Or use the %install shortcut
%install dplyr
Note: Only R packages compiled to WebAssembly are available. See repo.r-wasm.org for the package list.
Switch to R using the language selector. The webR runtime (~50 MB) downloads on first use and is cached.
# Basic math
mean(c(10, 20, 30))
# Vectors and stats
x <- rnorm(100)
summary(x)
# Static plot (PNG)
plot(1:10, (1:10)^2, main = "Quadratic")
# Interactive Plotly chart
plotly(1:50, sin(1:50 / 5), title = "Sine Wave")
# Multi-trace interactive chart
mplotly(
traces = list(
list(x = 1:10, y = (1:10)^2, name = "x²"),
list(x = 1:10, y = (1:10)^3, name = "x³")
),
title = "Power Functions"
)
# Cross-kernel file sharing
sharedfs_write("/shared/data/from_r.txt", "Hello from R!")
sharedfs_list("/shared/data")
Switch to Prolog using the language selector (Py → PL).
% Assert facts
assert(parent(tom, bob)).
assert(parent(bob, ann)).
% Query
parent(tom, X).
% Rules
assert((grandparent(X,Z) :-
parent(X,Y), parent(Y,Z))).
grandparent(tom, Z).
SciREPL has a SharedVFS (shared virtual filesystem) that lets all kernels read and write to the same files. Files under /shared/ and /tmp/ are accessible from every language.
Directory layout:
/shared/data/ — Datasets (CSV, JSON, etc.)/shared/lib/python/ — Python modules (auto-added to sys.path)/shared/lib/prolog/ — Prolog modules/shared/lib/wasm/ — WebAssembly modules/shared/bin/, /shared/config/ — Utilities and config files/tmp/ — Temporary files (shared, not persisted)Per-kernel behavior:
open() with /shared/ paths. Files are synced to SharedVFS automatically after each cell execution.sharedfs_write() and sharedfs_read() helpers to access shared files./shared/ paths directly.# Python — write a CSV to the shared folder
with open("/shared/data/results.csv", "w") as f:
f.write("x,y\n1,2\n3,4\n")
# R — read it back
sharedfs_read("/shared/data/results.csv")
% Prolog — consult a shared knowledge base
:- consult('/shared/lib/prolog/kb.pl').
Packages, bundles & workbooks: When you install an item from Browse Packages, Bundles & Workbooks, bundle dependencies are installed first and files with /shared/ destination paths are written to SharedVFS automatically. Package files targeting a specific kernel (e.g., Prolog modules at /user/) go to that kernel's own filesystem.
Browsing files: Open Menu → Files & Storage to browse. Select SharedVFS from the dropdown to see shared files, or select a kernel (Python, Prolog) to see its internal filesystem. Use the Show empty folders checkbox to toggle visibility of empty directories.
Uploading: Use the "Upload File" button at the top of Files & Storage to upload files directly into SharedVFS. Set the destination path (default: /shared/data/) before uploading.
Export Document — Choose a document format and image handling:
.html.zip with an images/ folder. references in a .md.zip..tex file for academic papers. Uses listings, amsmath, booktabs, graphicx. Exports as .tex.zip if images are present.Export Workbooks & Packages — Export notebooks and data:
%%magic commands (e.g. %%r, %%bash). Viewable in Jupyter, Colab, VS Code, and GitHub. Use this to share notebooks with others.Syntax highlighting: Code cells display with syntax highlighting for Python, JavaScript, R, Bash, Prolog, and Lua. Exports (HTML, DOCX) also include highlighted code.
.ipynb import with outputs: When importing a .ipynb file that already contains outputs, they are displayed directly without re-executing the code. This allows fast viewing of notebooks from Jupyter, Colab, or previous SciREPL exports.
Switch to Lua using the language selector. The Fengari runtime (~200 KB) downloads on first use from CDN.
-- Tables (arrays and dictionaries)
t = {10, 20, 30}
print(#t, t[1])
-- Closures
function counter(start)
local n = start
return function() n = n + 1; return n end
end
c = counter(0)
print(c(), c(), c())
-- Coroutines
co = coroutine.create(function()
for i = 1, 3 do
coroutine.yield(i * i)
end
end)
print(coroutine.resume(co))
print(coroutine.resume(co))
-- Pattern matching (built-in, no regex needed)
s = "Hello World 123"
print(s:match("(%a+)%s+(%a+)"))
-- Read another cell's output via Notebook VFS
prev = nb.read("In[1]", ".output")
print("Cell 1 said: " .. (prev or "(empty)"))
-- Write to a named cell (name a cell "results" first)
nb.write("results", ".code", "print('updated by Lua!')")
-- WARNING: overwrites the first cell's code!
nb.write("In[1]", ".code", "print('overwritten by Lua')")
Every cell is accessible as a virtual file at /nb/. You can read and write cell code, output, language, and name from any kernel. Cells can be addressed three ways:
/nb/my_cell/.code (user-assigned cell name)/nb/In[1]/.code (1-based position)/nb/-1/.output (previous cell), /nb/+1/.code (next cell), /nb/./.code (self)Properties: .code, .output, .language, .type, .name
Bash — uses filesystem paths directly:
# By name
cat /nb/my_cell/.code
# By index
cat /nb/In[1]/.output
# Relative: previous cell's output
cat /nb/-1/.output
# Self-reference
cat /nb/./.code
# Write to a cell
echo "print('hello')" > /nb/In[3]/.code
# List all cells
ls /nb/
Python — nb_read() / nb_write():
# By name
code = nb_read("my_cell", ".code")
# By index
output = nb_read("In[2]", ".output")
# Relative (previous cell)
prev = nb_read("-1", ".output")
# Write generated code to a named cell
nb_write("results", ".code", "print('generated!')")
# List all cells
cells = nb_list()
R — nb_read() / nb_write():
# By name
code <- nb_read("my_cell", ".code")
# By index
output <- nb_read("In[2]", ".output")
# Write to a named cell
nb_write("plot_cell", ".code", "plot(1:10)")
# List cells
cells <- nb_list()
Lua — nb.read() / nb.write():
-- By name
code = nb.read("my_cell", ".code")
-- By index
output = nb.read("In[2]", ".output")
-- Relative: previous cell
prev = nb.read("-1", ".output")
-- Write to a named cell
nb.write("results", ".code", "print('from Lua')")
-- List all cells (returns JSON)
cells = nb.list()
Prolog — nb_read/3 / nb_write/3:
%% By name
nb_read('my_cell', '.code', Code).
%% By index
nb_read('In[2]', '.output', Output).
%% Write compiler output to another cell
nb_write('r_factorial', '.code', GeneratedCode).
JavaScript — direct window.notebookVFS API:
// By name
const code = window.notebookVFS.readFile("/nb/my_cell/.code");
// By index
const out = window.notebookVFS.readFile("/nb/In[1]/.output");
// Write
window.notebookVFS.writeFile("/nb/In[3]/.code", "console.log('hi')");
Tip: Give cells a name (click the cell label) so other cells can address them by name instead of fragile index numbers.
Each cell remembers its language. To change a cell's language, click ✎ to edit, then use the language dropdown. Click All→ to apply the language to all code cells in the notebook.
▶↓
Run All Below
Put #!source on the first line of a named TypR or Lua cell to keep highlighted code available through the Notebook VFS without executing it. The remaining directives are TypR-specific:
#!source — the cell shows Source only, intentionally has no Out [n], and remains readable through the Notebook VFS.#!typecheck — type-check the following code without executing it.#!transpile — show the transpiled R code.#!show-r — toggle generated R display for subsequent TypR executions.Open Menu → Languages to show or hide languages in the cell dropdown. Unchecking a language removes it from the selector but doesn't unload its runtime. All languages are enabled by default. Your preferences are saved across sessions.
Runtime versions: R and Prolog show the tested default, latest available, current selection, and successfully loaded session source separately. Leave the version and source fields blank to use the exact tested default. R accepts a webR tag such as v0.5.4; latest is rolling and unverified. Prolog accepts a compatible npm-swipl-wasm selector such as 3/8/2; its global latest is an incompatible package line and is rejected, so use Check latest for the newest compatible 3.x release. Changes require a reload.
Full documentation: GitHub README
SciREPL
Includes: Multi-language (Python, R, Prolog, Bash, JavaScript, Lua), editable cells, markdown cells, session persistence with auto-save and crash recovery, Math Mode palette, .ipynb import/export with output preservation, .srwb workbook format, rich export (HTML, Markdown, PDF, DOCX with native equations, LaTeX) with syntax highlighting, virtual filesystem, search paths, URL file fetching, multi-notebook support, package catalog with one-click install, language settings, package format (.zip/.tar.gz)
This release makes SciREPL easier to learn, personalise and trust.
Space above the header, so the app does not sit under the device status bar. Auto follows the device's reported safe area. Set 0 to remove it entirely.
Scales the header buttons. Larger buttons are easier to hit on a touchscreen.
Keep frequently used tools in the header. Hidden shortcuts can be re-enabled here at any time.
A theme is a set of colour variables. Edit the values below, then apply. Unknown names and non-colour values are rejected.
Raw CSS, applied last. This can make the app unusable — use Reset to defaults to recover.
Only languages with a usable translation are listed. File extensions and kernel names stay in their original form in every language.
Lists languages whose translation has not been checked by a speaker yet, so it can be reviewed in the app. Turn this on if you are helping review a translation.
Enable or disable languages in the cell dropdown.
One-click install packages, dependency-aware workbook bundles, and individual workbook templates into SciREPL.
Choose a verified SciREPL Catalog channel. Latest stable and release channels use a static host without the GitHub API.
Compatible mirrors must use HTTPS, publish the same release layout, and allow browser cross-origin reads. Loopback HTTP is accepted for local testing.
Upload any file to the shared filesystem, accessible from all kernels.
Browse persistent storage and kernel-specific filesystems.
Configure file_search_path/2 for module resolution.
| Alias | Directory |
|---|
Download a file from a URL into the virtual filesystem.
% After uploading myfile.pl:
:- consult('/user/myfile.pl').
% After adding search path mylib → /user/mylib:
:- use_module(mylib(module_name)).
% Fetch and load from URL in a cell:
fetch_file('https://example.com/kb.pl', '/user/kb.pl').
:- consult('/user/kb.pl').
% Or use load_url (fetch + consult):
load_url('https://example.com/kb.pl', '/user/kb.pl').
Last updated: August 15, 2026
SciREPL is designed to be a privacy-respecting application. All code execution happens locally on your device. We do not collect, store, or transmit any personal data to our servers.
SciREPL stores data locally on your device using browser or app storage, including localStorage, IndexedDB, and caches:
SciREPL does not send this local data to its servers. You can clear session and VFS data via Menu > Clear History, downloaded runtime and app caches via Menu > Memory & Storage, and verified catalogue snapshots, cached workbook artifact bytes, and trusted release mappings via Browse > Catalog source > Clear verified data. Clear verified data does not remove installed catalogue notebook copies; delete those notebooks individually or use Menu > Clear History.
SciREPL bundles its core interface and most language runtimes directly in the app. The following items describe what is bundled and what may be downloaded from third-party services:
webr.r-wasm.org, downloaded when R is first used and cached locally.cdn.jsdelivr.net or unpkg.com, downloaded when Lua is first used and cached locally.docx@9.6.0 from cdn.jsdelivr.net, downloaded when DOCX export is first used.s243a.github.io) and immutable catalogue or workbook bytes from raw.githubusercontent.com. These requests do not intentionally include notebook content, search text, spoken-language choices, fallback preferences, or kernel filters. Selecting a development branch additionally asks api.github.com to resolve it to an exact commit. Other packages and user-requested data may be fetched from package repositories or URLs when you request them, for example with install.packages(), %pip, or file-fetching commands.ko-fi.com. No Ko-fi request is made unless you choose to open it.When these resources are fetched, the CDN providers may receive:
Caching minimizes repeat connections. After a runtime or package is downloaded, SciREPL uses a local cached copy when available. Verified catalogue snapshots, downloaded catalogue workbook artifact bytes, and trusted release mappings are also stored locally; clear those from Browse > Catalog source > Clear verified data. This does not remove installed catalogue notebook copies; delete them individually or use Menu > Clear History. Built-in catalogue items remain available.
jsDelivr's privacy policy: jsdelivr.com/terms/privacy-policy-jsdelivr-net
Your code, session data, and exported files are not transmitted to a SciREPL server. Network requests occur only for the resources described above or when your code explicitly requests them.
SciREPL provides a file-fetching feature that allows notebook code to download files from URLs you specify. When you use this feature (e.g., fetch_file in Prolog, or via the Prolog Settings panel), the request is made directly from your device to the specified URL. The remote server will receive your IP address and standard HTTP headers. SciREPL does not proxy, log, or monitor these requests.
Code you enter in the included Python, Prolog, Bash, JavaScript, R, Lua, TypR, and ClojureScript kernels is executed locally on your device. No code is sent to a SciREPL server for execution.
When you export a notebook (.ipynb), the file is created locally on your device. If you choose to share it (via the system share sheet), the destination is determined by your choice. SciREPL does not control or monitor where you share exported files.
SciREPL does not include any analytics, crash reporting, advertising SDKs, or tracking mechanisms.
SciREPL does not knowingly collect any information from children. The app does not require account creation or collect personal information of any kind.
If a future release changes which runtimes or packages are bundled or downloaded, this policy will be updated to describe the resulting network requests and metadata exposure.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR PERFORMANCE THEREOF.
You use SciREPL entirely at your own risk. Code execution occurs locally on your device and the developers are not responsible for any consequences of code you choose to run.
This runtime requires a download. It will be cached by the browser for future use.
Downloading...