What this site does with your data
Last updated 26 September 2026. This page covers the website. The iOS and Android apps have their own policy, and it is a shorter one, because those apps have no account and make no network requests.
The short version
- Every lesson works without an account. Nothing about you is needed to read this site.
- Code and input you type run in your browser and are never sent to us.
- No advertising, no ad networks, no selling or sharing data with anyone for marketing.
- No analytics service is currently receiving anything at all. If one is ever added, the section below is how it will be asked for.
- An account exists to remember your progress. Deleting it deletes everything keyed to it.
Reading without an account
You can open every lesson, track and topic without signing in. When you do that, the things the site remembers are written into your own browser and stay there. Nothing in this table is sent to us, and clearing your browser data removes all of it.
| Stored as | What it is for |
|---|---|
as:progress | Where you are in a lesson, and which you have finished, for readers without an account. It is never uploaded. |
as:track | Which learning track you are following, so a lesson can offer the next stop on it. |
as:theme | Light or dark, when you have chosen rather than followed your system. |
as:consent | Your answer about measurement, and when you gave it. |
as:lang | The language you prefer to read code listings in. |
as:sound | Whether the player makes a sound. |
as:predict-intro | Whether you have already seen the one-time explanation of predict mode. |
as:code:* | A draft of what you have written in “write it yourself”, per lesson and language, so closing the tab does not lose it. |
as:session | A short-lived note of whether you are signed in, to save asking the server on every page. Cleared when the tab closes. |
If you make an account
An account does one thing: it remembers your progress and your answers across devices. That is the whole reason it exists, and the list of what is kept is short enough to print.
| Kept | Why |
|---|---|
| Your email address | The account is the address. It is how you sign in and the only way to reach you. |
| A password, hashed | Only if you set one. Stored as an Argon2id hash, never as the password. Sign in by emailed link and there is nothing to store. |
| A name, if you give one | Shown on your dashboard. It is optional and it can be blank. |
| Your sessions | One row per browser you are signed in on: when it started, when it expires, and that browser’s user-agent string, so an unfamiliar one is recognisable. The cookie itself is a random token and only its SHA-256 is kept, so reading the database does not yield a usable session. |
| Lesson progress | Per lesson and example: the step you reached, how many there were, and when you finished it. |
| Predictions | Per question: which step, which option you chose, whether it was right, and when. This is what a readiness score and a review queue would be built from. |
| Your email choices | Which optional email you have agreed to, all of it off unless you turn it on. Sign-in links, confirmations and receipts are not in here: there is no setting for them, because they are answers to something you did. |
Progress you built up as a guest is not uploaded when you sign in. It stays in the browser that recorded it, and the account starts its own.
Your code and your input never reach us
Running a lesson on your own values, and writing your own implementation and testing it against a lesson's cases, both happen inside your browser. JavaScript runs in a Web Worker; Python runs on Pyodide, which is Python compiled to WebAssembly. There is no server that executes anything you write, which means there is nothing for us to store, read or leak.
The one thing to know: Pyodide is about ten megabytes and is fetched from the public jsDelivr CDN the first time you run Python, not from us. That request is made by your browser, so jsDelivr sees your IP address and browser the way any site you visit does. Nothing about the lesson or your code is included in it. The visualization engine and the fonts are served from this site, so no other outside service is contacted.
Cookies
Two, both first-party, neither for advertising:
as_session- your sign-in, set when you sign in and cleared when you sign out. It cannot be read by scripts, is sent only over HTTPS and lasts thirty days.as_hint- a signed, fifteen-minute note of who you are that the page can read, so drawing the header does not cost a database query on every page view. It carries your account id, address, name and whether the address is confirmed.
Everything else the site remembers is browser storage rather than a cookie, and is in the table above.
Measurement, and how you are asked
As of 26 September 2026 no analytics or product-measurement service is configured on this site, and nothing is being sent to one. What exists is the machinery for asking, built before any vendor, so that turning one on cannot skip the question:
- In the EU, the EEA and the UK nothing loads until you agree. That is the default there, not a setting.
- A browser sending Global Privacy Control, or the older Do Not Track, is treated as a refusal without being asked.
- You can change your mind at any time, from the footer of any page or here: .
- Your address, your name and anything you type are never part of what would be measured. Before you sign in the identifier is random; after, it is a hash of your account id.
Server logs
The web server keeps an access log: the IP address, the page requested, the time, the status and the browser's user-agent string. It is kept for about ninety days, and it exists for two reasons - finding out what broke, and seeing which search and AI crawlers are reading the site, which no analytics tool can answer because a crawler runs no JavaScript. It is not used to build a profile of a reader and is not shared.
Sign-in attempts are rate limited per address and per IP. Those counters live in memory and are never written down.
Who else is involved
- Resend sends the email: sign-in links and address confirmations today, and receipts and notices as those exist. They receive the address the email goes to and the text of the message. They do not receive your progress or anything else, and they tell us when an address bounced or reported us, which is what the do-not-send list is built from.
- jsDelivr serves Pyodide, as described above, and only if you run Python.
- The host that runs the site and its database.
Nobody else. Data is not sold, not shared for advertising, and not handed to anyone for their own purposes.
Keeping it, and deleting it
Progress and predictions are kept while the account exists, because the account exists to keep them. Sign-in links and address-confirmation links expire within hours and are single-use. Sessions expire after thirty days.
Deleting the account takes everything with it - progress, predictions, sessions, your email choices and any unused sign-in links - in one operation and for good. It is in your settings, and it asks you to type your address back first. What deletion removes is written out in full. If you would rather ask than press it yourself, write to the address below.
There is a gentler option next to it: switching the account off signs you out everywhere and stops every optional email, while leaving your progress where it is. Signing in again turns it back on. Most people looking for a delete button want that one, and it is there so that wanting to be left alone does not cost you your work.
One thing deliberately survives it. If you have unsubscribed, or an email to you bounced or was reported as spam, the address stays on a do-not-send list, and deleting the account does not clear it. The alternative is worse: forgetting that you asked to be left alone, and starting again the next time that address appears. It holds the address and the reason, nothing else, and writing to us removes it.
Children
The site is meant for students aged 13 and over. Accounts are not knowingly created for anyone younger. If you believe a child has made one, write to us and it will be removed.
Your rights
Depending on where you live you can ask for a copy of what is held about you, ask for it to be corrected, or ask for it to be deleted, and you can object to processing or withdraw consent. Three of those you can do yourself, immediately, in settings: download everything held about your account as a file, correct your name and address, and delete the account. For anything else write to contact@nublabs.com and you will get an answer within 30 days. If you are in the EU or UK you can also complain to your national data protection authority.
Changes
If this ever starts collecting something it does not collect today, this page changes before that ships, with a new date at the top - not after. The current version is always at this address.
Contact
contact@nublabs.com. Questions about this page, requests about your data, or anything else on contact.