1. Home
  2. Guides
  3. Setting it up

Setting it up

Updated ยท Markdown

From nothing to your own live site. About twenty minutes, most of it waiting for things to finish.

Want your own name, logo and domain? Run npm run rebrand first (Part G).

You need:

  • A Mac or PC with Node 20 or newer (nodejs.org, the LTS button).
  • A Cloudflare account. Free to make.
  • A card for Cloudflare. R2 storage asks for one even on its free tier.

Every command below runs in a terminal, inside the project folder.


Part A. Try it on your own laptop first

Five minutes. Nothing goes online.

1. Install.

npm install

2. Tell it who the owner is. Copy the example settings file:

cp .dev.vars.example .dev.vars

Open .dev.vars and put your email after OWNER_EMAIL=.

3. Build the local database.

npm run db:migrate:local

4. Start it.

npm run dev

5. Open http://localhost:8787/app/. Make your account with the email from step 2. Press Take the tour, then Present. Open the join link on your phone (same wifi) or in another browser window.

Stop it with Ctrl + C.


Part B. Put it online

B1. Make a Cloudflare account

Go to dash.cloudflare.com/sign-up. Confirm your email.

B2. Switch on R2

R2 is where slides, pictures and the room's photos live. Cloudflare asks you to switch it on once.

  1. In the Cloudflare dashboard, find R2 Object Storage in the left menu. It may be inside Storage & databases.
  2. Press Purchase R2 Plan. The free tier is 0 dollars.
  3. Add a card if asked, and confirm.

Nothing is charged unless you go far past the free tier. At the time of writing that is 10 GB stored, and millions of reads a month.

B3. Run the setup

npm run setup

What happens:

  1. It installs what it needs, if Part A did not already.
  2. A browser window opens. Sign in to Cloudflare and press Allow. If your login has more than one Cloudflare account, it asks which one.
  3. It makes the database, the storage bucket and the tables.
  4. It publishes the site.
  5. It asks for your email. That account becomes the owner.

It remembers the site in sites.json, so later commands know where it is. At the end it prints your address. It looks like:

https://joocy.your-name.workers.dev

If anything stops it, it says why and what to do. Fix that one thing and run npm run setup again. It skips whatever is already done.

On a brand new Cloudflare account it may stop at publishing and ask you to pick a workers.dev subdomain first. That is one screen: dashboard, Workers & Pages, type any name you like, confirm. Then run npm run setup again.

B4. Make your account

Open https://YOUR-ADDRESS/app/#/signup. Sign up with the same email you gave the setup. You are the owner.

B5. Check everything is connected

In the app, open Admin (top bar). The first three lines must be green:

LineIf it is not green
DatabaseRun npm run db:migrate, then reload.
File storageCheck R2 is switched on (B2), then npm run setup again.
Live roomsRun npm run deploy again.

The others are optional.

B6. A real test

  1. Press Take the tour on your Presentations page.
  2. Press Present. The stage opens in a new window.
  3. Scan the join code with your phone.
  4. Press the right arrow on the stage. Your phone follows.
  5. Answer on your phone. The screen counts it.

That is the whole thing working.


Part C. Before your first real talk

The free plan is fine for trying things. For a real audience, switch to Workers Paid: 5 dollars a month.

Why: the free plan allows each request only a few milliseconds of work. Signing in (the password check) and saving a big deck can go past that. Paid also raises every other limit a full room might touch.

How: dashboard, Workers & Pages, Plans, choose Paid.

On the free plan, if signing in fails with error 1102: open wrangler.toml, find # PBKDF2_ITERATIONS = "20000", delete the #, and run npm run deploy. Upgrading is the better fix.

C2. Your own address (optional)

Want su.mr or talk.yourname.com instead of workers.dev? See Part H, "Your domain". In short: put the domain on Cloudflare, in the same account as the site, and the setup attaches it for you.

C3. Password reset emails (optional)

Without email, a locked-out presenter asks you, and you make them a reset link in Admin, under Presenters, then the menu next to their name.

To send reset emails on their own:

  1. Make a free account at resend.com.
  2. Add and verify your domain there (it shows the DNS records to add).
  3. Make an API key.
  4. Store it, and the sender address:
npx wrangler secret put RESEND_API_KEY
npx wrangler secret put MAIL_FROM

For MAIL_FROM type something like Joocy <hello@yourname.com>.

C4. Invite other presenters

New sites only let in people with an invite. Admin, Invites, Make an invite link. Send the link. Or switch Who can sign up to Anybody.


Part D. Updating later

When there is a new version of the code:

npm install
npm run deploy

It asks which site, if you have more than one, brings that site's tables up to date (only adding what is new, never touching your decks), then publishes. npm run deploy -- --all updates every site, one after another.


Part E. What it costs

For one talk to a hundred people, a few cents at most, usually nothing:

  • Slides, pictures and the app itself come from Cloudflare's edge for free.
  • Each phone holds one connection to the live room. Answers and reactions are small messages on it, counted twenty to one by Cloudflare.
  • Phones that cannot hold that connection fall back to asking once every couple of seconds, and those answers are cached at the edge for a second, so a whole room costs about one request a second.

Workers Paid (5 dollars a month) covers far more than one presenter will use.


Part F. Running a beta

  1. Keep sign ups on invite. In the app, Admin, Invites: make one link per tester, or one link with several uses for a group.
  2. Ask each tester to try the things that differ from talk to talk:
  3. their own deck: a PDF, a Keynote HTML export, or a deck exported as a video;
  4. a few questions, presented to real phones on a real wifi;
  5. their own AI, with a key from Your AI.
  6. Watch it live while they test:

``bash npm run tail ``

Every request is one line. If anything breaks on a screen (the stage, a phone, the console, the app), the screen reports it, and it shows up here as a client.error line saying what failed and on which page.

  1. Admin, Is everything connected says whether the database, files and live rooms are all answering.

Nothing a tester does is lost: every save is a version, deleted decks wait in the trash, and only a person signed in to the app can delete anything for good.


Part G. Your own name, logo and domain

Everything your audience and your presenters see takes its name from one file, brand.json. To change it:

npm run rebrand

It asks for each thing, showing what it is now. Press Enter to keep one.

  1. The name, written the way you want it seen. For example sumr.
  2. A short name for web addresses and Cloudflare. Lower case, no spaces.
  3. The tagline. For example add sunshine to your presentations.
  4. Your domain, if you have one. For example su.mr.
  5. The logo: drag an SVG or PNG file into the terminal. Any size: the bigger, the crisper.
  6. The tab icon: a square picture, or Enter to use the logo. A wide logo squeezed into a tab is hard to read, so a square icon is better.
  7. Does the logo spell the name? Say yes for a wordmark (the name, drawn), and pages show the logo alone. Say no for a symbol, and pages write the name next to it.

It puts the new name in page titles and link previews, the logo on every page, the guides, what your AI reads, and the names a new site gets.

The pictures are made ready for the web: trimmed to their edges, made small (a few megabytes from a designer become about 60 KB), every icon size browsers and phones ask for, and a picture for link previews when somebody shares a join link in a chat. Then:

  • see it on your laptop: npm run dev
  • show it on your site: npm run deploy

Run it again whenever you like. It always starts from brand.json, so it knows the current name, whatever it is now.

Keys your AI already has keep working; new keys start with the new short name. A few things keep the old name inside, where nobody sees them (a header the app sends itself, the deck file format, cookie names): changing those would break saved decks, keys and sign ins.


Part H. More than one site

The same code can run several sites: a test site and the real one, each with its own presenters, decks and address. Each is its own Cloudflare Worker, database, file storage and live rooms; sites on one account share only that account's plan. sites.json lists them, and each command asks which one.

A new site, on another Cloudflare account

For the launch, say, on an account of its own:

  1. Rebrand first (Part G), so it starts with the right name.
  2. Make the new Cloudflare account and switch on R2 there (B1, B2).
  3. Run npm run setup and choose Set up a new site.
  4. Choose another Cloudflare login. A browser opens: sign in as the new account.
  5. It asks for the site's name (Enter takes your short name), and whether to put it at your domain.
  6. It makes the database, storage and tables there, publishes the site, and asks for the owner email. Then B4 to B6, on the new address.

Your test site carries on as it was. From then on npm run deploy asks which site, and each command checks you are signed in as the login that owns it, offering to switch if not.

Tip: in the new account, invite your usual login as a member (Manage Account, then Members). One login then reaches both, and nothing asks you to switch.

If it stops halfway (R2 not switched on, say), fix what it says and run npm run setup again. Choose Finish setting up: it carries on from where it stopped.

Your domain

To put a site at su.mr, the domain has to be a website in the same Cloudflare account as that site:

  1. In the dashboard, Add a domain, type su.mr, choose the free plan.
  2. Where you bought the domain, change its nameservers to the two Cloudflare shows you.
  3. Wait until Cloudflare says Active. Minutes, sometimes a few hours.
  4. Run npm run setup. A new site offers to go at your domain. For a site you already have, choose it and say yes when it offers the domain.

It sets up the address and its HTTPS for you. Not Active yet? Setup offers to publish without the domain for now. Run it again once it is Active, choose the site, and it attaches the domain. Phones then join at su.mr/K7M4P.


Part I. The offline app

Joocy Offline runs a room on a presenter's own computer when the venue has no internet (Offline mode). It needs your site to have offline mode, so deploy first (Part D).

Try it on this Mac

npm run desktop

It builds the app and opens it. Link it to your site, copy a deck, start the room. Nothing is signed: it is for this Mac.

Make it for other people

So it opens on any Mac without warnings, it is signed with your Apple Developer ID and notarized by Apple. Once:

  1. In Xcode, Settings, Accounts, Manage Certificates, add a Developer ID Application certificate (or make one at developer.apple.com). Check it is there: security find-identity -v -p codesigning.
  2. At account.apple.com, Sign-In and Security, App-Specific Passwords, make one called "notarize".
  3. Find your Team ID at developer.apple.com, Membership.

Then, with your own values:

APPLE_ID=you@example.com APPLE_APP_SPECIFIC_PASSWORD=abcd-efgh-ijkl-mnop APPLE_TEAM_ID=ABCDE12345 npm run desktop:dist

The first time, the Mac asks whether codesign may use your key: Always Allow. Signing and notarizing take a few minutes. The disk image lands in desktop/dist/, about 185 MB.

Windows

npm run desktop:dist -- --win

It makes a Windows installer (x64) in desktop/dist/. Unsigned, Windows warns before it runs; a code signing certificate (or Microsoft's Trusted Signing) removes the warning. Test it on a real Windows computer before handing it out.


When something is wrong

The site shows "Nothing here." You opened a path that does not exist. The app is at /app/.

Sign up says "You need an invite link". Sign up with the owner email first. Then make invites.

Sign up says "The owner has to sign up first". Someone tried before you did. Sign up with the owner email.

Error 1102 when signing in. See C1.

Setup could not attach your domain. The domain is not a website in that Cloudflare account yet, or its nameservers are still changing. Say yes to publishing without it for now, then see Part H.

"Already has externally managed DNS records" (code 100117). The domain is on Cloudflare, but an old address record is using the name, usually left by the company you bought it from. In the dashboard, open the domain, then DNS, Records. Delete the A, AAAA and CNAME records named after the domain (shown as the domain or @). Keep MX and TXT records: they are for email. Then run npm run setup again and pick your site. Your site stays up on its workers.dev address meanwhile.

Setup stopped halfway. Fix what it says, run npm run setup again and choose Finish setting up.

Deploy or setup is waiting a long time. Each step shows Cloudflare's own lines as they come, and "still waiting for Cloudflare" every 15 seconds. A connection can go silent: after a minute (tables) or three (publishing) it is stopped and tried once more. If that also goes quiet, it stops and says so. Check your internet connection and run it again; every step checks before it acts.

Setup says it needs a workers.dev subdomain. See B3.

Admin shows "File storage" red. R2 is not switched on, or the bucket is missing. B2, then npm run setup.

Phones say "There is no live session with that code". The session ended, or the code is mistyped. Press Present again.

Locked out, no email set up. From your laptop:

npm run owner:reset-link -- you@example.com

It asks which site, if you have several, and prints a link that works once, for an hour.

Watching what the site does, live:

npm run tail

Every request and every problem prints one line.

All guidesJoocy home