Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Collaborative JS
Search
Ben Foxall
August 10, 2016
Technology
170
1
Share
Collaborative JS
How to build a collaborative browser-based editor (and why)
Ben Foxall
August 10, 2016
More Decks by Ben Foxall
See All by Ben Foxall
Web Sites & Fairy Lights
benfoxall
0
130
Making Simple Things
benfoxall
2
270
Simpler Things
benfoxall
0
1.9k
Using Browsers to Visualise Data
benfoxall
0
96
Serving Data From Browsers
benfoxall
0
83
Building multi-device interfaces with the web
benfoxall
1
190
Other Decks in Technology
See All in Technology
実例から学ぶ GuardDuty(SSH BruteForce)調査の全体フローと勘所【SecurityJAWS】
cscengineer
PRO
0
170
Gaussian Splattingの表現力を拡張する — 高周波再構成とインタラクションへのアプローチ —
gpuunite_official
0
200
Databricks 月刊サービスアップデートまとめ 2026年04月号
tyosi1212
0
140
RedmineをAIで効率的に使う検証
yoshiokacb
0
160
論文紹介:Pixal3D (SIGGRAPH 2026)
tenten0727
0
630
障害対応のRunbookは作った、でも本当に動くの? AWS FIS で EKS の AZ 障害を再現してみた
tk3fftk
0
120
Pythonでベイズモデリング
soogie
0
150
AIのために、AIを使った、Effect-TSからの脱却 〜テストを活用した安全なリファクタリングの進め方〜
bitkey
PRO
0
170
Claude Code / Codex / Kiro に AWS 権限を 渡すとき、何を設計すべきか
k_adachi_01
6
1.9k
可視化から活用へ — Mesh化・Segmentation・アライメントの研究動向
gpuunite_official
0
240
Terragrunt x Snowflake + dbt で作るマルチテナントなデータ基盤構築プラットフォーム
gak_t12
0
510
Python開発環境にハーネス適用を検討する
yuuka51
0
140
Featured
See All Featured
<Decoding/> the Language of Devs - We Love SEO 2024
nikkihalliwell
1
210
sira's awesome portfolio website redesign presentation
elsirapls
0
250
Practical Orchestrator
shlominoach
191
11k
Unsuck your backbone
ammeep
672
58k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
35
2.4k
What does AI have to do with Human Rights?
axbom
PRO
1
2.1k
Lightning Talk: Beautiful Slides for Beginners
inesmontani
PRO
1
540
Bootstrapping a Software Product
garrettdimon
PRO
307
120k
Visualization
eitanlees
151
17k
Claude Code のすすめ
schroneko
67
220k
Redefining SEO in the New Era of Traffic Generation
szymonslowik
1
300
Mozcon NYC 2025: Stop Losing SEO Traffic
samtorres
0
230
Transcript
HELLO! I'm @benjaminbenben!
I work at @Pusher
None
I co-organise @JSOxford
None
I've not really said this stuff yet 1. Tell me
if we've been here too long 2. I'd be happy (and sorry) if you tell me this is rubbish
Live coding across all the things
Live coding across all the things
How to build a collaborative browser-based editor (and why)
䡿 Browser-based editors
None
side note - not just frontend
None
cojs.co
!
/
/ 䡿 The challenges
None
The challenges —Making a textarea feel nice —Showing content —Code
transpilation —External modules —Not breaking things
/ 䡿 The challenges Making a textarea feel nice
Web based code editors (maybe don't write one yourself) —Ace
Editor —Monaco —CodeMirror —~Atom~
None
Integration with our textarea CodeMirror.fromTextArea(source)
…tonnes more stuff
/ 䡿 The challenges Showing content <iframe id="target" href="/mypage"></iframe> (normal
answer: host it somewhere) !
Option 1.
"Upload" to ServiceWorker Web page → Service Worker → Network
hmmmmm —trendy —cool —persistant urls —overkill possibly —support is …
positive? —really cool
Option 2.
Data URIs
data:[<mediatype>][;base64],<data>
data:text/html,<h1>Hello! !
iframe.src = 'data:text/html;charset=utf-8,'+ '%3Cbody%3E%3Cscript%3E' + encodeURI(source.value) + '%3C/script%3E'
hmmm —lack of error handling —length limitations —random encoding issues
—restrictions…
None
Option 3.
Blobs new Blob(blobParts[, options])
b = new Blob(['…'], {type: 'text/html'})
b = new Blob(['…'], {type: 'text/html'}) url = URL.createObjectURL(b) //
"blob:https%3A/…/2084018…ab3a2cec02" // later URL.revokeObjectURL(url) !
var blob = generate(source.value) URL.revokeObjectURL(target.src) iframe.src = URL.createObjectURL(blob)
hmmm! —not stored on the stack —safe, and lots of
control —sounds cool
/ 䡿 The challenges Code transpilation
ES2015 const hey = (you) => console.log(`HELLO ${you}`) !
Tracuer Babel Bublé
All pretty cool, though personally ♥Bublé
Bublé —inspired by Babel —no shims / polyfills —compact transforms
only —less extensibility —fast —Nice one, Rich Harris
buble.transform(source.value).code
/ 䡿 The challenges External modules
// commonjs const utils = require('utils') utils.say('yeah!') // ES2015 modules
import {say} from 'utils' say('yeah!')
bundling !
Webpack Browserify Rollup
All pretty cool, though… ♥Rollup
Rollup —embracing ES2015 modules —minimal code-rewriting —tree shaking —d3, THREE.js
Rollup —embracing ES2015 modules —minimal code-rewriting —tree shaking —d3, THREE.js
—Seriously, Rich Harris you're the best
rollup.rollup({ entry: '__main__', plugins:[ { resolveId: (i) => i, load:
(id) => { if(id == '__main__') return source.value return fetch('/module/' + id + '.js') } } ] }).then(bundle => bundle.generate({ format: 'iife' }).code )
/ 䡿 The challenges Not breaking things
for(var i = 99; i > 0; i++) { console.log(`${i}
bottles of beer`) }
jsbin/loop-protect Super props, Remy Sharp loopProtect(`for(var i = 99; i
> 0; i++) { console.log(\`${i} bottles of beer\`) }`)
{;loopProtect.protect({ line: 1, reset: true }); for(var i = 99;
i > 0; i++) { if (loopProtect.protect({ line: 1 })) break; console.log(`${i} bottles of beer`) } !
/
/ 䡿 Why
Closing the loop
Closing the loop change, save, tab, ftp, wait, tab, refresh
Uploading stuff to a server
Closing the loop change, save, tab, refresh Local development
Closing the loop change, save Live reload+
Closing the loop change In place editing
This is a good thing
/ 䡿 Why Multi Device Development Experiments
/1 Collaboration
None
/2 Broadcast
/2.1 (Broadcast) For development
/2.2 (Broadcast) For talk-workshops
/3 Social inspired development
/
/ demo? let's build a "musical instrument"
People & user experience are the difficult things (so let's
focus on them)
Thank you, I'm @benjaminbenben (also, right here)