playhtml working log

things to revisit when you work on this project again

  • playhtml store, wholesale games
  • marketing clarify who this is for and how to market it “The issue is that I’m sort of serving two audiences currently. 1) html energy people who like to just write a plain html site by hand and 2) developers (even beginning ones) who have inherent preferences about the tools that they want to get things done with (myself being one of these people).”
  • web components ”- discovered shoelace, a library of common web components, which is great inspiration for playhtml, which should eventually offer web components to “templatize” the web (e.g. the noguchi lamps should be one)”
    • follow the pattern that google fonts uses to specify the precise components that are desired (how do they actually do this? is it generated on the fly based on the request)
  • sharing between sites#ideas/website for playhtml + archipelago
    • ^944d9b
    • figure out best mechanism for sharing an item between websites
      • how to make it both semi-secure and also super easy to set up
        • 1 option is have the same code duplicated
        • 2 have the code made once (a single instance) that’s hosted in my server? and you get a unique ID reference that everyone can create a web-component of <shared-element id=“….”>
          • maybe this works best as the store mechanism
    • can-take auth backed by cookie of account (or key that is somehow tied to your computer? cross-device doesnt really matter)
      • for each site with one of these things, they check this cookie to validate that you can interact with these
      • how to derive a stable id or key here though, like how do you make sure the cookie doesnt get deleted, extension?
        • simple extension that just authenticates you and fetches from the partykit
      • should be robust to people taking and not doing anything with it.. maybe its just not a single object or people just get the right to place it once
      • how to take most advantage of the real-time aspect… how can these interactions feel really live when most of them are happening async?
    • The real mind-breaking part of persistent + real-time is when you do it across different places (like playhtml’s store with the lamp on the front and inside the product page)
  • permissioning for doing things
    • also allow people to create custom permissions on the fly… as you navigate around a personal website you get permission to move things..
    • how to get stable ID for people?
      • browser fingerprinting is one way, but this can change potentially..
      • some gateway for public key discovery (potentially using bluesky/atproto keys or just a PGP key of your email..?)
        • this is how crypto wallets work..
      • how about UCAN?
      • maybe for now a centralized repository that is transparent / open? and then transition to UCAN when it is production-ready
  • local vs. multiplayer behavior API - researching this and also web component support and getting really confused about the best API and model here to make everything work across platform. I want 1. a generic and easy way to store state specific to a component where I can programmatically determine how its syncing and persistence (sync collaboratively & persist, sync collaboratively & don’t persist, don’t sync & persist (locally), don’t sync and persist (remotely)). Ideally I can also easily add on specific capabilities that other people have already created state handlers for without having to code it myself (can-move) * the first part points strongly to a state management library that sort of goes on top of Yjs so you don’t have to worry about their collaborative types.. but can you really abstract that away? It seems like this only works for simple data structures that are just keys in an object, but once you get to actual complex objects and arrays, i think the end-programmer needs ultimate control on how to merge new synced data… So how much can you really abstract away? 2. a way to get wholesale components from people who have designed it (with state management, styling, and everything included). - i guess this isn’t really new but the new part is that you have all the state sync and persistence built in? - can i get this with pure web components and stencil? it seems like they support children natively (just not any knowledge of them) - I could bundle all the capabilities into web components to make it react-like and then it would just work across all platforms, like <moveable>
  • cron things using new cron api..
  • speculative API explore what julius tarng meant with exposing the outputs of things and a more folk-like wish syntax
  • example make a portfolio site with it
  • custom persistence
  • should be able to easily access data from other elements (use ID to reference) and
    • change the hierarchy from tag -> element -> data to elementID -> { tag -> data }
    • also should be able to easily just program global data? that is synced at a website level? i guess this is basically awareness but they need to not collide with each other. ideally would not nest them unless there are several tags..?
  • make it reactable
    • right now im just piggybacking off the native javascript dom interaction code for initializing state into dom elements… what would i do if i were just supporting react?
      • probably a provider that manages all this state..
      • as soon as a CanPlay element is mounted, register with provider and render based on state from provider, upon unmount delete from registry..
    • worth to do this if it simplifies development and/or improves performance
    • ok honestly probably not worth as long as i optimize my flow

Behaviors to try out

  • drawing
  • ambient presence indicators
    • color hover instead of cursor
    • color fingerprints
  • can-rearrange
  • can-hover
  • can-scroll
  • can-resize
  • can-zoom
  • can-highlight


make something that creates a world out of websites

  • a small data-tag that you can attach to any element that makes it “takeable” and any place that makes it “placeable”
    • can-take
    • can-place
    • can-move
    • can-draw
    • can-age


  • how to do this without prohibitive data costs?
  • how to do this with API key or no account creation / no custom javascript required?

API design

Handling react vs. vanilla

issue right now is that the state changes are not automatically hooked up to the react changes. Although this likely only happens when it doesn’t pass the ref down to the parent DOM element properly… but I can’t control being able to forward ref down for custom elements.

  • @playhtml/core - shared primitives
    • a function that setups up all the state and stores it on the window
    • a function for re-initializing new
  • @playhtml/react
  • @playhtml/vanilla

plug-and-play this is intended for immediate use and consumption. Effectively “templates” that you can plug and play with your own data.

<div can-move style="font-size: 80px">🛋</div>

Ideally, these high-level templates are composed of the lower-level functions that can also be used on their own.

low-level functions option 1: persist just the data, make it accessible on the actual html element as a data attribute?

<div onDrag="onDrag">
	function onDrag(e, currData) {
		let x = currData.x + e.clientX - this.startMouseX
		let y = currData.y + e.clientY - this.startMouseY = `translate(${x}px, ${y}px)`;
		return {x,y} 
// after library effects
<div onDrag="onDrag" playhtml-data="{x,y}">
  • is it better to store as data attribute or in localStorage?
    • for simple things I like data attribute because it’s all visible and parseable from the DOM but for longer data it’ll pollute the DOM…
    • it’s already being stored in indexeddb.. I should just provide some easy accessor of global variables to access all that data

option 2: persist style update for that function

<div onDrag="onDrag">
	function onDrag(e, currTransform) {
		const currData = parse(currTransform)
		let x = e.clientX - this.startMouseX
		let y = e.clientY - this.startMouseY
		return 'transform: translate(${x}px, ${y}px);'
// after library effects
<div onDrag="onDrag" style="transform: translate(${x}px, ${y}px)">
  • this is less flexible than the option 1, but a bit simpler since you just have to worry about the actual CSS properties of the affected element

Project Log

I’m attempting to build this using partykit

  • partykit is quite nice but i should use yjs… the real pain is just working in vanilla HTML which im not familiar with

  • what happens when multiple people are dragging at the same time?

    • build in indicators that it’s being acted upon for things that have an ongoing action
    • how to handle conflicting actions:
      • only allow one person at a time to do it
      • build in resistance?

security considerations what to worry about here?

accounts do we need identities/accounts associated with people?

  • for can-take and can-place will probably require some kind of association of “this is mine” unless there are infinite ones to take
    • could require the extension for these.
  • apparently partykit is working on auth and presumably will have identities then

name brainstorming

html, websites, play, collaborative, fun, together, handmade

  • open-websites
  • playsites
  • playsite
  • playhtml (playdough)
  • freehtml
  • bricolage
  • moss
  • coral
  • guest
  • lichen
  • archipelago

for demo

  • start with showing we-bsite and talk about the background and motivation? [1min]
  • go into the demo [1min]
  • show the code [1min]
  • talk about extensions and future [1min]

posting into reddit Whenever I work on a personal project, I find myself wanting to add these bits of presence (that remember their state) but it’s so much of a hassle to spin up a database and add on collaboration for a small project, so I made this library to make it super easy to share and persist state across HTML elements and on websites generally.

I want the internet to feel more alive and for real-time collaborative technology to be used for more fun and personal uses! and this has felt like a fun move in that direction.

Demo: Github: