HackerReposA FIELD GUIDE TO OPEN SOURCE
ProSponsor the shelf♧ 0
← Back to top all-time
joy-framework
joy
Janet2020–2026
joy-framework / joy

joy

A full stack web framework written in janet

7Distinct people
15Mentions
0Explicit recommenders
615GitHub stars
REPOSITORY AT A GLANCE

What to know before exploring

What it is

A full stack web framework written in janet

GitHub

Where it is used

No documented product use has been verified yet.

What people are saying

No recommendation phrase was found in the indexed comments.

No classified warning is attached to this page. Read the discussions before treating silence as approval.

Also in these discussions

Mentioned in the same Hacker News threads. That is not proof they are substitutes.

This week on Hacker News

Nov 7–Nov 14 UTC · Direct repository links and separately labeled related project stories. Indexed through 11/14/2026, 12:54:37 PM UTC.

No direct repository links were found in the indexed HN discussions over the past seven days. Older discussions are available below.

Mentions over time

HN mentions by year15 dated mentions

Observed mentions: 2020-03-21 19:59:12 UTC to 2026-06-02 16:43:54 UTC.

012342020-01-01 00:00:00 UTC to 2021-01-01 00:00:00 UTC (exclusive): 3 mentions; 0 submissions, 3 comments20202021-01-01 00:00:00 UTC to 2022-01-01 00:00:00 UTC (exclusive): 3 mentions; 0 submissions, 3 comments2022-01-01 00:00:00 UTC to 2023-01-01 00:00:00 UTC (exclusive): 3 mentions; 0 submissions, 3 comments2023-01-01 00:00:00 UTC to 2024-01-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments20232024-01-01 00:00:00 UTC to 2025-01-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2025-01-01 00:00:00 UTC to 2026-01-01 00:00:00 UTC (exclusive): 2 mentions; 0 submissions, 2 comments2026-01-01 00:00:00 UTC to 2027-01-01 00:00:00 UTC (exclusive): 4 mentions; 0 submissions, 4 comments. Incomplete calendar period.2026*

* An incomplete calendar period is marked with an outlined bar. Its count is not directly comparable with a full period.

Counts come from the repository’s dated source evidence. Index cutoff: 2026-11-02 08:16:59 UTC.

View mention counts and date ranges
UTC ranges include their start and exclude their end. Select a period to filter the source evidence.
PeriodStart (UTC)End (exclusive, UTC)MentionsSubmissionsComments
20202020-01-01 00:00:00 UTC2021-01-01 00:00:00 UTC303
20212021-01-01 00:00:00 UTC2022-01-01 00:00:00 UTC303
20222022-01-01 00:00:00 UTC2023-01-01 00:00:00 UTC303
20232023-01-01 00:00:00 UTC2024-01-01 00:00:00 UTC000
20242024-01-01 00:00:00 UTC2025-01-01 00:00:00 UTC000
20252025-01-01 00:00:00 UTC2026-01-01 00:00:00 UTC202
2026 (partial)2026-01-01 00:00:00 UTC2027-01-01 00:00:00 UTC404

What Hacker News says

15 sources
> I never thought it could happen to me. But I am truly biased. I have basically forgotten how to code everything else (besides APL family languages) in the past _checks notes_ 10 months since I started Janet. I even run a community [docs site](https://janetdocs.org/) and am writing [my own tutorial](https://janetdocs.org/tutorials/learn-to-program) (albeit slowly). I even use it in production for all new software (within 3 weeks of starting, I had rewritten all personal scripts etc.) > Janet is simple You can do literally everything with just hashmaps. The whole language is basically a hashmap, implementation wise. `(keys (curenv))` prints out all locally defined symbols. `(keys (getproto (curenv)))` prints the parent hashmap of the current environment i.e. all the core symbols. I don't, but you can basically do CLOS via hashmaps (and th
Read the rest
ere is a [fuller implementation](https://git.sr.ht/~subsetpark/fugue) too.) > Janet is distributable I have like 20 websites and another dozen or so services running on Janet (with the [Joy webframework](https://github.com/joy-framework/joy) which I wrote a [tutorial](https://janetdocs.org/tutorials/Joy-Web-Framework) for), on a single free-tier VPS with 512mb of RAM. > Janet has ... immutable collections ...not really. In reality, the whole standard library constantly returns mutable versions from everything. There's no reason to really try to be immutable at this point. Although there are cool [combinator libraries](https://git.sr.ht/~subsetpark/apcl-janet) and I've even made combinatorish versions of basic functions: (defn better-cond [& pairs] (fn :bc [& arg] # names for stack traces (label result (defn argy [f] (if (> (length arg) 0) (apply f arg) (f arg))) # naming is hard (each [pred body] (partition 2 pairs) (when (argy pred) (return result (if (function? body) (argy body) # calls body on args body))))))) Combinatory inspired cond, which allows for pairs. The test does not need an argument and the body may be a simple value or a function: (map (better-cond string? "not a number" odd? "odd" even? "even") [1 2 3 "cat"]) # the args! (map (better-cond 1 (fn [arr] (array (min ;arr) (max ;arr)))) # (recombine array (unapply min) (unapply max))) (partition 2 (range 10))) # these are the args! ((better-cond < "first is smaller" > "second is smaller") 5 3) # these are the args passed into the func! I am excited! > Janet lets you pass values from compile-time to run-time That's what got me hooked, in a few ways. In Racket or Go, I had to do a lot of work to process data at compile time so the runtime could literally just be a lookup table. In Janet? That's the default behavior of any `def` outside of main. The following turns a .tsv of the bible into a hashmap in the binary, when compiling: (def verses (reduce (fn [acc line] (let [parts (string/split "\t" line)] (if (= (length parts) 5) (let [[_ abbrev ch vs text] parts] (put-in acc [abbrev ch vs] text)) acc))) @{} (string/split "\n" (slurp "kjv.tsv")))) (def abbrev-array (keys verses)) # also makes an array of the abbreviation column So the rest of the program is literally just accessing the hashmap ([twice as fast](https://codeberg.org/veqq/verse-reader#performance) as the Golang version using `embed`): (defn main [_ & args] (if (or (empty? args) (= "-h" ;args) (= "help" ;args)) (do (print "Usage: kjv <book> [chapter:verse]") (os/exit 1))) # show help (let [Capitalized (string (string/ascii-upper (string/slice (first args) 0 1)) (string/slice (first args) 1)) book (find |(string/has-prefix? $ Capitalized) abbrev-array)] (pp (match args [_ chap verse] (get-in verses [book chap verse]) [_ unsure] (match (string/split ":" unsure) [chap verse] (get-in verses [book chap verse]) [chap] (get-in verses [book chap])) [_] (verses book))))) The equivalent go program was 5x longer and required an extra program to convert data into a 40k line .go file with a giant literal hashmap, to be faster than the naive Janet. ...but actually Ian Henry means Janet e.g. keeps closures synced across images/sessions: (defn timer [t] (var t t) # this is slightly annoying, must shadow as params are immutable [(fn [] (set t (+ t 1))) (fn [] (set t (+ t 2)))]) (def tx (timer 0)) # call like this: ((tx 0)) ((tx 1)) # make an image and save it to file (def my-module @{:public true}) (spit "test.jimage" (make-image (curenv))) Exit and start a new REPL session: (defn restore-image [image] (loop [[k v] :pairs image] (put (curenv) k v))) (restore-image (load-image (slurp "test.jimage"))) ((tx 0)) It saved the closure and all relevant image in the `(curenv)` hashmap. Condensed from my longer response: https://lobste.rs/s/y0euno/why_janet_2023#c_lspe6n
In Why Janet? (2023)
> can actually be extended in useful ways I just made a library with [query syntax](https://codeberg.org/veqq/declarative-dsls) over various data structures a la sql: (import declarative-dsls/dataframes :as df) (def people (df/dataframe :name :age :job)) (df/dataframe? people) (df/insert! {:name "Bob" :age 30 :job "Developer"} :into people) (df/insert! {:name "Alice" :age 27 :job "Sales"} :into people) (df/update! :set {:job "Engineer"} :where |(= ($ :job) "Developer") :from people) (df/save-csv people "people.csv" :sep "\\t") (def people2 (df/load-csv "people.csv" :sep "\\t")) (-> people2 df/dataframe->rows df/rows->dataframe df/print-as-table) Printing: job age name -------- --- ----- Engineer 30 Bob Sales 27
Read the rest
Alice It also has datalog and minikanren (with s expr, sharing the same goals etc.) And it vectorizes like APL: (df/v + [1 2 3] 1 [1 2 3] 1) # returns: [4 6 8] (df/v + 1 {:column [1 2 3] :key [1 2 3]}) # returns: {:column @[2 3 4] :key @[2 3 4]} (df/v * [1 2 3] [[1 1 1] [1 2 2] [1 2 3]]) # returns: @[@[1 1 1] @[2 4 4] @[3 6 9]] Or you can just use [J directly from Janet](https://git.sr.ht/~subsetpark/jnj): (jnj/j "3 4 $ i. 10") # returns: ((0 1 2 3) (4 5 6 7) (8 9 0 1)) (jnj/j "$" [3 4] (range 10)) # returns: ((0 1 2 3) (4 5 6 7) (8 9 0 1)) The Joy Web Framework has a cool [db query dsl](https://github.com/joy-framework/joy/blob/master/docs/databa...) too: `(var account (db/find-by :account :where {:login (auth-result :login)}))`, used for a [web auth](https://codeberg.org/veqq/janetdocs/src/commit/848dcbd8e54ad...). From my response, bigger than the article: https://lobste.rs/s/y0euno/why_janet_2023#c_lspe6n
In Why Janet? (2023)
I manage some client websites made with https://github.com/joy-framework/joy for example https://codeberg.org/veqq/janetdocs/ Some email stuff I don't know how to summarize well Some data processing/aggregation servers Some accounting stuff I'm trying to build a declarative DSL https://lobste.rs/s/ylq7sd/what_are_you_doing_this_weekend#c... which I could port production Common Lisp/Prolog stuff to, but I probably won't for performance reasons.
In Show HN: I made a Clojure-like language in Go, boots in 7ms
Janet has ~10 web frameworks (half SSG, half dynamic) and many web servers. Joy [0] is the most fully featured stack approach, which Janetdocs [1] runs on. But everything you mention is in the std lib. Here's a certbot in 10 lines only using the extended std lib (called spork): https://codeberg.org/veqq/janetdocs/src/branch/master/ssl-fe... `json/decode` automatically maps json to native data structures. There's a package manager included, which builds all code I've found so far, reproducibly. As for DS, only arrays, there are maps, arrays and strings, all mutable or immutable. I don't think there's any intention to ever implement functional data structures, but they could "easily" be a library. - [0] https://github.com/joy-framework/joy - [1] http://janetdocs.org/
In Janet: Lightweight, Expressive, Modern Lisp
Tangential but I’ve been writing a lot of Janet recently using Joy[0], web framework, to build a small web app. Would love to hear what you learned about Janet from doing this work and how you feel about the language afterwards. The one thing I’ve noticed is that it seems like Janet had a burst of interest 2020-2022 but it has since slowed down. Would love to see it become popular again. The main reason I’m using it is because I like how it’s both powerful and lightweight. I’d use clojure but I don’t want Java. I’m tempted to also try Common Lisp but so far Janet has been great. [0]: https://github.com/joy-framework/joy
In Show HN: A Tiling Window Manager for Windows, Written in Janet
Hmm I see, that link may be a bit unfortunate, as it only shows the introduction to the docs. More pages are here: https://github.com/joy-framework/joy/tree/master/docs#readme PS: I did a very minor contribution to Joy once, so minor that I actually forgot about it :) I don't use Joy myself at the moment as I'm using my own framework, but the Joy docs + source code helped me out a lot in figuring out how to do authentication, csrf, etc!
In Joy: A maximalist web framework for Lisp aficionados
Most of what you're asking for is described in the docs, with examples. If you're looking for an example project using Joy, I think janetdocs[0] may be a good example. Some Janet experience may be good before diving into that repo, because it imports Joy with `:prefix ""`. Also keep in mind that 99% of this seems[1] to have been made by 1 guy (Sean Walker), I think in his free time. [0]: https://github.com/swlkr/janetdocs [1]: https://github.com/joy-framework/joy/graphs/contributors
In Joy: A maximalist web framework for Lisp aficionados
>Node.js comes so close but anemic standard library The nodejs API is rather big really. If you're using Ruby as your standard of normal sized almost everything would look small in comparison, but "anemic" is a stretch. You'd really hate Lua. If you're taking suggestions, you might enjoy Janet[1]. It has a pretty large user API, lots of bells and whistles included in the standard libs like you'd find in Ruby, and lots of different ways to achieve the same result like Ruby. It's been a while since I checked out the ecosystem, but I was _very_ happy with the Joy Framework[2]. It definitely doesn't come close to the scope of Rails, but I think it _does_ near Rails in it's easy of use for the developer with it's scaffolding, controller generation etc. [1]: https://janet-lang.org/ [2]: https://github.com/joy-framework/joy
In Where is Ruby Headed in 2021?

MAKE YOURSELF AT HOME

A few shortcuts

/
Search the collection
?
Open this guide
Esc
Close dialogs and navigation

Your saved repositories and interests stay in this browser.