• Stars
    star
    127
  • Rank 282,790 (Top 6 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created over 5 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

The fastest, easiest way to build and deploy quick static webpages

Codeframe

Codeframe is the fastest, easiest way to build and deploy quick static webpages, and it's designed to be the best place to learn how to create things for the web, on the web. You can find it running live at codeframe.co.

Codeframe.co

Why Codeframe?

👋 It's easy to use. Codeframe is built first and foremost for quick experiments and for people learning to code for the first time, so it eschews complexity and additional features for simplicity and ease of use.

🚀 It's fast. Your development environment should move at the speed of your ideas, and with no build tooling, there's no reason Codeframe can't be instantaneous. I built Codeframe to cut down the time from idea to sharable prototype as much as physically possible. Just open the editor, write code, and share in one click.

🛠 It's open-source and fully inspectable. Everything that runs Codeframe, from the backend stack to the JavaScript code behind the Codeframe editor, is open source and inspectable right in the browser. I think having readable source code in the delivered product makes a difference for people learning to code, and Codeframe prioritizes this over additional complexity and small efficiency gains with minified bundles and proprietary source.

Why not Codeframe?

If you don't specifically need something designed for speed or for students new to coding, there are other tools that might work better for you, with more features. CodePen is the classic in-browser web IDE with more powerful features and customization options; CodeSandbox is awesome for experimenting with projects with build / bundling steps, and Repl.it has an amazing suite of development tools for their HTML environment, including the ability to create additional files / folders and multiplayer, which allows for smooth real-time collaboration.

Run your own Codeframe

Everything you need to run your own version of Codeframe is in this open-source repository. Here's how you can run your own version on Codeframe on your computer or server.

You'll need these tools:

  • git, for copying the repository from GitHub to your computer. Get Git here.
  • Node.js for running the Codeframe app, which is written in JavaScript for Node.js. Download Node.js here.
  • npm (or its alternative yarn) to install dependencies like Express. NPM typically comes with Node.js.
  • A command line terminal, and basic familiarity with how to move around your computer in it with ls, cd, etc.

Once you have these tools installed and ready, the first step is to clone this git repository to your computer. Go to a directory where you'd like to setup Codeframe, and run

$ git clone https://github.com/thesephist/codeframe.git

(If you have SSH set up for git, and know how to use it, you can use the git:// url instead. If you don't, don't worry about it.)

Now, cd into the new codeframe directory git just created, and you should see all the files in the Codeframe repository.

$ cd codeframe/
$ ls
src/    static/   docs/   README.md  LICENSE ...

Here, let's try starting Codeframe with Node.js using the command npm start.

$ npm start
...
Error: Cannot find module 'express'
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:603:15)
    ...

This means Node.js couldn't find express, a JavaScript library to build web servers that Codeframe depends on. Let's install dependencies like Express by running npm install, then try again.

$ npm install
...
$ npm start
Codeframe running on localhost:4556

You may notice that npm creates a new directory called node_modules/, where it'll install Codeframe's dependencies.

If you see the message Codeframe running on localhost:4556, this means you have Codeframe up and running on your computer. Go to your browser and open up the address http://localhost:4556. This should tell your browser to find the page running on port 4556 (Codeframe's default port) on your computer, and load up the main page of Codeframe.

After you change any backend-service file (under src/), you can restart the server with npm start (Ctrl + C to end a running server) to see the changes take place. If you're editing frontend code, there's no need to restart -- just reload the page in the browser!

How does Codeframe work?

If you're curious about the inner-workings of Codeframe, I'm building out a fully annotated version of the codebase available here on GitHub Pages using a tool called Litterate. While that's a good place to look at how everything is implemented, this section provides a high-level overview of how the system is designed.

Backend: Hash-based immutable database

All codeframes are (for now) a pair of files, an HTML file and a JavaScript file, which we can just treat as chunks of text. Codeframe stores all files, both HTML and JavaScript, in the same place, in the same way, in a way that can't be modified once they're saved. This is Codeframe's immutable, hash-based database.

When a user creates a new file or a new version of a file, the editor sends the file to the backend. The backend gets the file and hashes it (currently using SHA256) and uses the hash to create a short and practically unique filename for the file. The file is saved to a location in the backend (db/ by default) with that hashed filename. This makes sure that, if we tried to save the same file multiple times, we'd effectively only save one file in the backend. Because this happens a lot in practice using Codeframe, this is efficient.

Each file is identified by its hash in this way, so using two hashes (one each for the HTML and JavaScript files of a Codeframe), we can define any unique Codeframe. This is how Codeframe works; each Codeframe's URL contains two hashes, one each for HTML and JavaScript. When you request a Codeframe, the backend finds files saved before using those hashes as filenames, and returns the files to the editor or to the browser for your viewing.

This hash-based database of files has a few advantages. The fact that each file is saved once and never overwritten means that any Codeframe, at any point in time, is completely characterized by its URL. Your changelog is effectively your browser history, and any Codeframe you share will stay exactly that version forever. This also means the backend service remains extremely simple -- it's a completely functional design with no side effects outside of the database, which is an immutable key-value store.

The currently implementation, which is just based on the filesystem, also falls short in some areas. Mainly, it uses the FS as the storage layer of the database. Since filesystems aren't designed to be used this way, in large numbers we may hit a scalability bottleneck where we'll have to switch to a different key-value store like Amazon's S3. We also currently store incremental changes to each file in a completely separate file in the database. This is also the way Git handles changes, but with Codeframe's usage, this may turn out to be massively inefficient. These arne't issues at the moment, but may become more important going forward, at which point we'll address them.

Frontend: Embeddable, Torus-based editor

Codeframe's frontend user interface is built as a single Torus component, which is the Codeframe editor. This editor can run standalone, as it does in the full-screen editor view of any Codeframe, or it can be embedded as an <iframe> into certain allowed websites, like it is on the main page. Everything else you see on the frontend, including the rest of the home page, is simple, handwritten HTML, CSS, and JavaScript.

I chose Torus to build the frontend because (1) I wrote the library, so I know it inside-out and it's designed to fit my tastes, (2) it's fast and lightweight, just like Codeframe is designed to be, and (3) it makes prototyping very, very fast; Codeframe's v1.0 was built in 20 hours over 2 days, so fast prototyping was a priority while things like support for older browsers wasn't a core goal. It was also a good chance to let Torus stretch its legs and test it out in a production setting.

The entire editor is implemented in a single JavaScript file, in static/js/main.js, which you can read here.

For the text editor inside Codeframe, on Desktop browsers, I'm using Monaco, a text editor built for the browser from Microsoft's Visual Studio Code editor. It's fast, sleek, and works very well on desktop browsers. Monaco's mobile support is lacking, however, so on mobile browsers, we ship a different editor, CodeMirror. CodeMirror is used widely in Chrome DevTools and Glitch, among other tools, is lightweight and fast to load, and far more usable on mobile browsers than Monaco. The experiences of using both editors are at near parity for the basic experience, while each editor brings some smaller feature enhancements over the other. You can read about how we achieve this pluggable architecture in the "pluggable editor backend" section below.

The preview pane in the editor is a simple <iframe> that opens a view of the generated HTML + JS page for the Codeframe, so you can see it as it updates live. Today, it operates completely independently from the editor, but in the future we may add some communication between the two to make fancier features possible, like live updates.

A note on frontend dependencies

Codeframe's editor only has a single core dependency: Torus, which is a lightweight UI framework. For development speed, Codeframe currently ships the dependency as a simple <script> tag in the editor HTML that points ot the most recent version of the NPM package on Unpkg. In the future, we may bundle Torus with a compiled version of our editor script. But so far, Unpkg has proven reliable enough.

A pluggable editor backend

Codeframe's code editor portion is not itself contained in this codebase. Although there is a reference implementation of a very bare-bones editor here implemented as a <textarea>, in production, as explained above, Codeframe uses either Monaco or CodeMirror as the code editor of choice, depending on the client (mobile versus desktop browsers). We can shift easily and reliably between these three editors and potential other ones in the future because the Codeframe frontend interfaces with the editor through a small set of APIs that can be implemented around any reasonable code editor. We call this set of APIs the EditorCore interface.

Codeframe ships with EditorCore wrappers for both Monaco and CodeMirror, and chooses to load one or the other at runtime depending on the client (if we aren't using an editor, no part of that editor's code is loaded in the browser). If we were to switch to a different editor backend or swap out an editor with another one in the future, this wrapper architecture with a small API surface makes this very easy -- a few hours at most to wrap the interface around a new editor. As long as the editor wrapper implements the interface correctly, the editor will work with rest of Codeframe.

How to contribute (beginners welcome 👋)

Codeframe is open-source for two reasons.

  1. To share how it works inside, so anyone curious can learn from it, and
  2. To allow anyone to contribute improvements and templates to Codeframe.

Improve Codeframe itself

To the second point, there are lots of corners of Codeframe that are rough and can use some polish. If you're an experienced JavaScript developer and want to see Codeframe improve, my DM's and PR's are open.

Add explanations and clarifying comments or notes

But more importantly, I made Codeframe open-source with the intention that newcomers to web programming would be able to learn from reading Codeframe's source. If you come across a bit of code in the repository that confuses you, feel free to file an issue or add a pull request for better explanations, clarifications, or better code.

Add starter templates

A key part of Codeframe is its library of friendly starter templates. It's a small set for now, but I want to grow this into a repository of high-quality sample Codeframes that allow people to jump in and learn about new web technologies easily.

If you have Codeframes or samples you'd like to include on the front page of Codeframe as another starter template, add a file under starter_fixtures/ and inside const STARTER_FIXTURES in src/models.js, and file a pull request! Starter templates set up this way are set up in the database at deployment time, ensuring that every running version of Codeframe has it set up.

Miscellaneous notes and interesting questions

Infinite loops and the halting problem

One of the key features of the Codeframe editor is its "reload as you type" feature. That is, in the default mode (with the feature enabled), the editor will periodically reload the preview pane with the code from the editor, sometimes in the middle of typing. This generally makes for a superior editing experience -- without switching what we're doing, we get to see the result of our code immediately as we're editing, and that tight feedback loop is great for development.

However, in certain cases, especially when writing JavaScript, this means that the preview reloads in the middle of typing, when we're writing potentially invalid or buggy JavaScript. One such buggy behavior that we might inadvertently reload into the preview pane is an infinite loop. In certain contexts, for example when we're writing for(){} and while(){} loops, we may create an infinite loop in the middle of typing our program that gets reloaded into our preview window, which by design grinds the entire editor tab to a halt, and results in potential data loss on the edits made in the editor.

Codeframe isn't the first editor to run into this, and CodePen.io has an interesting approach to instrumenting JavaScript in a live-reloading setting to prevent this behavior. The problem is challenging because preventing infinite loops in the general case is impossible -- it's a classic variant of the halting problem. In CodePen's case, they instrument the generated JavaScript code, such that when the same loop runs continuously for more than some period of time or iterations, it stops the loop. It's a pragmatic, albeit inelegant solution. Glitch, by contrast, does nothing to prevent infinite loops in live reloading settings.

I've found that, in practice, it's fairly rare to accidentally write syntax-valid JavaScript code that also results in infinite loops. And for those rare cases, Codeframe has an option to disable as-you-type reloading in the editor. But by default, Codeframe follows Glitch's precedence in not modifying or instrumenting JavaScript to prevent infinite execution. If we run into more use cases where this becomes an issue, we may revisit this problem.

"Saving" or "exporting" Codeframes

A neat side-effect of the simplicity of the code you can write on Codeframe (no compile step, no bundling) is that the output you get in a preview HTML page is verbatim the code you typed into the editor, plus some wrapper HTML code. So rather than explicitly add an "export" button or menu item, the user can simply open the preview and save the HTML document itself to "export" any codeframes they've created.

Support

If you enjoy using Codeframe and want to support what I make going forward, please consider making a donation to Codeframe through PayPal or Venmo 🙏.

Alternatively, please consider donating to some of the best nonprofit organizations doing great work in the CS education space, KhanAcademy, Hack Club, and StuTech.

More Repositories

1

monocle

Universal personal search engine, powered by a full text search algorithm written in pure Ink, indexing Linus's blogs and private note archives, contacts, tweets, and over a decade of journals.
JavaScript
1,472
star
2

ink

Ink is a minimal programming language inspired by modern JavaScript and Go, with functional style.
Go
557
star
3

blocks.css

Add some dimension to your page with blocks 🚀
HTML
466
star
4

tabloid

A minimal programming language inspired by clickbait headlines
JavaScript
457
star
5

torus

Torus is an event-driven model-view UI framework for the web, focused on being tiny, efficient, and free of dependencies.
JavaScript
321
star
6

revery

A personal semantic search engine capable of surfacing relevant bookmarks, journal entries, notes, blogs, contacts, and more, built on an efficient document embedding algorithm and Monocle's personal search index.
JavaScript
273
star
7

unim.press

A Reddit front-page reader in the style of The New York Times.
JavaScript
244
star
8

oak

An expressive, simple, dynamic programming language.
HTML
231
star
9

polyx

Productivity suite written from scratch in Ink on the backend and Torus on the web
JavaScript
212
star
10

libsearch

Simple, index-free full-text search for JavaScript
JavaScript
159
star
11

merlot

Web based Markdown writing app built with isomorphic Ink and Torus
JavaScript
150
star
12

h12y

The email service for when just "hey.com" isn't enough.
HTML
147
star
13

modelexicon

This AI Does Not Exist: generate realistic descriptions of made-up machine learning models.
CSS
145
star
14

draw

Real-time collaborative whiteboard on the web
JavaScript
126
star
15

inc

A note-taking tool based on the principles of incremental note-taking, designed for quickly capturing fleeting ideas and growing a knowledge base over time.
Makefile
126
star
16

histools

A collection of tools for generating data visualizations from browser history data
JavaScript
125
star
17

mira

A place for notes, but for the people I keep in touch with
JavaScript
116
star
18

tinyhumans

A little interactive sandbox for tiny people, tiny thoughts, and their tiny stories
HTML
116
star
19

lucerne

A Twitter reader designed for learning from the Twittersphere, built with Ink and Torus
JavaScript
115
star
20

calamity

Self-hosted GPT playground
CSS
110
star
21

stream

A Twitter-like micro-blog for personal project updates and snippets of thought, written in Oak
CSS
83
star
22

burds

Just some burds, jumpin' around in their own little world.
JavaScript
81
star
23

thingboard

A board of things, anywhere you want on the screen
JavaScript
67
star
24

ycvibecheck

Semantic search across every YC company ever. Vibe check your idea?
CSS
57
star
25

lovecroft

Minimal mailing list manager for static sites, with a simple JSON API
Go
57
star
26

frieden

My personal, read-only public availability calendar
JavaScript
55
star
27

paper.css

Lightweight, modern CSS to add some flair to your web-things 📜
HTML
41
star
28

klisp

A Lisp written in about 200 lines of Ink, featuring an interactive literate programming notebook
JavaScript
38
star
29

superstat

Git status + diff across every repo in a directory
Makefile
35
star
30

typogram

Small, minimalistic graphics for powerful ideas in a few words
JavaScript
34
star
31

plume

Small in-memory real time chat server with Go and WebSockets
Go
33
star
32

september

Ink to JavaScript compiler and toolchain, written in Ink itself
JavaScript
29
star
33

yolo

On the yolo page, anything goes... I'll merge any pull request you make to this website.
HTML
28
star
34

x-oak-notebook

Experimental tool for writing dynamic Markdown docs that embed interactive explorable visualizations
HTML
28
star
35

maverick

Web IDE and REPL for the Ink programming language, written in pure Ink on a self-hosted compiler toolchain
JavaScript
27
star
36

pico

Lightweight notepad for ephemeral memos, todos, meeting notes, and more
JavaScript
26
star
37

zone

A URL shortener / note sharing service.
JavaScript
25
star
38

kin

A refined tool for exploring open-source projects on GitHub with a file tree, rich Markdown and image previews, multi-pane multi-tab layouts and first-class support for Ink syntax highlighting.
JavaScript
24
star
39

august

Assembler from scratch written in Ink, supporting ELF on x86_64 and more.
Assembly
23
star
40

codesynth

Generate music from your source code 🎹
JavaScript
23
star
41

albatross

A simple to-do list app
CSS
23
star
42

spectre

Sparse autoencoders for Contra text embedding models
Jupyter Notebook
23
star
43

cornelia

Guess that Taylor Swift line <3
JavaScript
22
star
44

hfm

Hugging Face Download (Cache) Manager
Makefile
21
star
45

sistine

A simple, flexible, productive static site generator written entirely in Ink
HTML
21
star
46

shelf.page

An online, public “blog-shelf” for collecting and sharing interesting reads with your audience. What's on your digital shelf?
JavaScript
21
star
47

clozoom

Close your Zoom meeting tabs automatically
JavaScript
20
star
48

carlisle

A minimal template for a Hugo site
CSS
20
star
49

zerotocode

The best place on the web to learn to make stuff with code
HTML
19
star
50

litterate

Generate beautiful literate programming-style description of your code from comment annotations
JavaScript
19
star
51

xin

Xin (신/心) is a flexible functional programming language with a tiny core, inspired by Lisp and CSP
Go
19
star
52

animated-value

Imperative animation API for declarative UI renderers, like React, Preact, and Torus.
JavaScript
18
star
53

schrift

A more experimental runtime for Ink, focused on perf and instrumentation
Rust
17
star
54

rush

Rush lets you work on many files at once
Makefile
17
star
55

eliza

A modern port of the ELIZA conversational program to pure Ink to run as a command line and in the browser.
CSS
15
star
56

entr

A searchable repository of my personal notes from readings
JavaScript
15
star
57

sounds

A collection of sounds from places I've been
JavaScript
15
star
58

micropress

An Ink library for automatic text summarization
14
star
59

dotink

dotink (.ink) is the Ink programming language's blog, and my general technical blog
HTML
14
star
60

matisse

Gallery of generative art written with Ink
HTML
12
star
61

socialite

Fast social sharing metadata tag generator
JavaScript
12
star
62

traceur

Experimental pathtracing 3D renderer written in Ink
Makefile
12
star
63

tsqdm

TQDM for TypeScript / Deno
TypeScript
12
star
64

xi

A dynamic, stack-based concatenative toy programming language.
Logos
11
star
65

ink-vscode

Support for the Ink programming language in Visual Studio Code
10
star
66

x-oak-klisp

A Klisp (scheme-like flavor of Lisp) implementation in Oak
Vim Script
9
star
67

wintermute

Generating fake blog posts from my blog with a Markov chain
Go
8
star
68

looking-glass

A simple web screenshot API using Puppeteer
JavaScript
8
star
69

lambda

The untyped lambda calculus, implemented in Ink
8
star
70

etch

Dead simple project scaffolding for my commonly used layouts
CSS
7
star
71

oak-syntax-visualizer

Oak syntax visualizer, made for GopherCon 2021
CSS
7
star
72

vanta

Port of thesephist/klisp to pure Go
Go
6
star
73

dotfiles

Config, scripts, rc files 💻
JavaScript
5
star
74

ky

A modal text editor
Go
5
star
75

rational-arithmetic

A no-dependency, lightweight JS library for arithmetic with rational numbers
JavaScript
5
star
76

inkfmt

Code formatter for the Ink programming language
Shell
4
star
77

markovify

Using Markov chains to naively generate sequences of words from training samples.
JavaScript
4
star
78

nought

Personal people-manager, what some people might call a personal CRM
HTML
3
star
79

dessi

A quick, simple server-side-includes expander
JavaScript
3
star
80

papyrus

Small, static-site for hosting read-optimized content, like stories or e-books
HTML
3
star
81

codeliner

Generate codelines: like silhouette outlines, but for your source code
3
star
82

inker

Web API to run Ink code on any device 💻
JavaScript
3
star
83

state-of-startups-bearx

BearX's State of Startups Report
HTML
3
star
84

web-audio-workshop-2020

Web Audio API Workshop for Hack the Fog and hackswiftly 2020
JavaScript
3
star
85

send-tweet

Small Ink program to send tweets using the Twitter JSON API
2
star
86

korona

Take any JavaScript data and get back a reasonably unique hex or rgb color with an optional alpha channel 🖌
JavaScript
2
star
87

strat

Minimal framework for futures, options, and cryptocurrency investments built on the Robinhood (private) API
JavaScript
2
star
88

brandish

Visual branding for humans
JavaScript
2
star
89

hurricane

Zero-configuration, read-only JSON API proxy in front of an Airtable base
Go
2
star
90

traceur-web

Web and JavaScript port of thesephist/traceur
JavaScript
2
star
91

ittr

Small library of iterator-related utility functions for JavaScript
JavaScript
2
star
92

ansi.ink

Ink library for printing with ANSI escape sequences
1
star
93

pandora

A small, HTML5 quiz SPA
JavaScript
1
star
94

generator-vanilla-extension

Yeoman generator for simple chrome extensions
JavaScript
1
star
95

thesephist.github.io

Placeholder for personal website
HTML
1
star
96

pyro

Check if any of the routes in a list of critical routes of an app are failing
Go
1
star
97

sigil

My full-time to-do list and task manager 🔥
JavaScript
1
star
98

notepad

Short bash script to pull up $EDITOR
Shell
1
star
99

talaria

Inward-out gesture recognition in a wearable
Python
1
star
100

blocky-logos

Blocky logos, an exploratory creative project about logo and branding 🌁
HTML
1
star