Progress that vanishes is the fastest way to lose a player permanently. Saving is easy to add and easy to add badly.

Start local

localStorage in a browser holds a few megabytes of text, survives closing the tab, and needs no server or account. For a single-player game this is usually the whole answer.

Save a version number alongside the data from the very first release. When your save format changes — and it will — that number is what lets you migrate old saves instead of wiping them.

local-save.txt
Add saving to my game. State object: <paste it>

- Serialise to localStorage under one key, with a schema version.
- Load on startup; if the version is old, migrate it. If it's corrupt
  or unparseable, start fresh rather than crashing.
- Save on meaningful events, not every frame. Say what you chose.
- Wrap every read and write in try/catch — private browsing modes
  throw on access, and a save failure must never break the game.

Show me how I'd add a field to the state without breaking old saves.

That try/catch is not defensive padding. Private windows and blocked site data throw on localStorage access, and an unhandled throw at startup means a blank screen.

What not to save

Don't serialise your whole runtime state — functions, DOM nodes, image objects. Save the minimum needed to rebuild: level, score, unlocks, positions. Rebuild the rest on load. Saves that mirror your internal structures break every time you refactor.

Going to the cloud

You need accounts, a server and a database — a real step up in complexity. Worth it when players use multiple devices or you need leaderboards.

Two things go wrong. Conflicts: same account, two devices, two different progressions. Decide the rule now (last write wins, highest score wins, ask the player) and implement it deliberately. Trust: anything the client sends can be edited, so a leaderboard fed by client-reported scores will be full of impossible numbers within a week of anyone caring.

Keep saving locally even when you save to a server. The network fails; the player's afternoon shouldn't.