[{"data":1,"prerenderedAt":369},["ShallowReactive",2],{"project-40889951":3},{"id":4,"name":5,"line":6,"line_source":7,"title":8,"url":9,"domain":10,"maker":11,"posted_at":12,"year":13,"points":14,"comments":15,"rank_in_year":16,"shown_in_year":17,"top":14,"tier":18,"category":19,"subcategory":20,"format":21,"keywords":22,"reception":27,"sentiment":28,"stance_mix":29,"scored_comments":33,"aspects":34,"strip":38,"post_text":40,"what":41,"said":89,"maker_in_thread":200,"shape":210,"grid":214,"attempts":331,"same_week":332,"maker_shows":235,"maker_hidden":361,"reader_version":362,"card":363},"40889951","Matry (@matry\u002Fdom)","A JavaScript UI library for imperative JSX","title","Show HN: A JavaScript UI library for imperative JSX","https:\u002F\u002Fwww.npmjs.com\u002Fpackage\u002F@matry\u002Fdom","npmjs.com","danielvaughn",1720268052,2024,41,53,1413,3515,"shown","languages","ui library","library",[23,24,25,26],"imperative jsx","dom manipulation","javascript ui library","jsx without react","mixed",-0.241,{"positive":30,"neutral":31,"mixed":32,"critical":31},1,6,0,13,{"design":35,"idea":37},{"positive":32,"critical":36},3,{"positive":30,"critical":36},[30,32,30,32,32,32,36,32,30,32,32,32,32,32,32,32,32,32,32,32,32,36,32,30,32,32,32,39,32,36,36,32,30,36,32,30,32,36,32,32],5,"I've been building a web UI library for a side project of mine. I thought it might be useful to others, so I'm releasing it as open source.\n\nTo put it simply, I realized that most of my pain points with React come from its declarative model ui=f(state). So I'm trying something that I'm calling \"imperative JSX.\" Instead of treating JSX as the source of truth for your UI, it essentially becomes a query interface for DOM manipulation.\n\nI first had the idea for it a few months ago, and only began writing it in earnest last week, so it's extremely early and nowhere near production-ready. Still, I'd",{"problem":42,"audience":54,"pricing":54,"motivation":55,"time_to_build":54,"stack":59,"openness":86,"stage":87,"team_size":88},{"value":43,"source":44,"evidence":45},"Pain points with React's declarative model for UI updates and imperative behaviors","maker",[46,48,51],{"id":47},"post",{"id":49,"by":11,"text":50},"40891465","Sure! There are several, but let's take a trivial one - setTimeout. This is an example of something that is inherently imperative, and therefore requires some awkward logic to…",{"id":52,"by":11,"text":53},"40916555","I also enjoy declarative UI. I hated imperatively building up the interface with jQuery, even with the helpers it just felt so tedious. This library is my attempt to have my cake…",null,{"value":56,"source":44,"evidence":57},"Side project pain points with React; released as open source in case it is useful",[58],{"id":47},[60,64,68,74,80],{"value":61,"source":44,"evidence":62},"JavaScript",[63],{"id":47},{"value":65,"source":44,"evidence":66},"JSX",[67],{"id":47},{"value":69,"source":44,"evidence":70},"xpath",[71],{"id":72,"by":11,"text":73},"40916788","Great question. So right now the library is using xpath expressions under the hood, which are more powerful than css selectors because they can query for content as well.",{"value":75,"source":44,"evidence":76},"mobx",[77],{"id":78,"by":11,"text":79},"40891936","Yeah I opted for quick, simple demonstrations of the basic ideas. In a real application, at least one of any significant complexity, I wouldn't be writing the code you see in…",{"value":81,"source":44,"evidence":82},"rollup",[83],{"id":84,"by":11,"text":85},"40897735","Yeah this is essentially what I'm doing. Though I'm fighting with rollup in the process. Might drop down to ESBuild if I need it.","open_source","prototype","solo",{"praise":90,"objections":106,"requests":138,"questions":150,"alternatives":165},[91,99],{"value":92,"source":93,"evidence":94},"Interesting novel idea worth discussing","commenter",[95],{"id":96,"by":97,"text":98},"40891867","justin_murray","It's cool to see a novel idea like this get prototyped and then opened up for discussion. As others have hinted at, this feels like jQuery with different syntax and more…",{"value":100,"source":93,"evidence":101},"Declarative JSX is appreciated for its clean structure",[102],{"id":103,"by":104,"text":105},"40921356","gedy","The only thing that is awkward imho is the focusing, the rest is a really good fit for declarative, e.g. here's your list of \"things\", render a UI for each.",[107,119,126,131],{"value":108,"source":93,"evidence":109},"Essentially jQuery with different syntax and more limitations",[110,111,115],{"id":96,"by":97,"text":98},{"id":112,"by":113,"text":114},"40918994","crubier","This is jQuery-like. Just syntax sugar above the imperative DOM API. Looks like the younger generation didn't know the pain of years of imperative UI \"frameworks\" and needs to…",{"id":116,"by":117,"text":118},"40891502","mati365","That's the worst idea for framework I've seen recently",{"value":120,"source":93,"evidence":121},"Lacks React's component isolation and state sync guarantees",[122,123],{"id":96,"by":97,"text":98},{"id":124,"by":97,"text":125},"40891978","Just a few more thoughts to add: When I see code like ``` count++; setContent(\u003Cp key=\"counter\">The count is {count}\u003C\u002Fp>); ``` I immediately think about how someone, at some…",{"value":127,"source":93,"evidence":128},"Global keys and selectors risk rogue DOM changes",[129,130],{"id":96,"by":97,"text":98},{"id":124,"by":97,"text":125},{"value":132,"source":93,"evidence":133},"Cleanup of timers and effects is not handled",[134],{"id":135,"by":136,"text":137},"40893073","SebastianKra","This is IMO a great example for React and declarative programming. > There's no special concept to understand By not understanding that you need to cleanup timers when your view…",[139,143],{"value":140,"source":93,"evidence":141},"Larger examples with widget reuse",[142],{"id":96,"by":97,"text":98},{"value":144,"source":93,"evidence":145},"Explain the pain points it solves",[146],{"id":147,"by":148,"text":149},"40891324","lgas","Can you talk a little about the pain points you encountered, which this presumably solves?",[151,158],{"value":152,"source":93,"evidence":153},"Why use JSX for querying instead of jQuery-style calls",[154],{"id":155,"by":156,"text":157},"40891348","gushogg-blake","Hmm, interesting. What advantages do you see of using JSX for querying over the old jQuery-style $(\"#id\").append(...)? Did you consider doing something more like that, but…",{"value":159,"source":93,"evidence":160},"Why not use template literals or CSS-like syntax",[161],{"id":162,"by":163,"text":164},"40916693","fbn79","Why not use template literals and a css like syntax for selecting and update? setContent(css`p[key=counter]{ content: 'The count is ${count}'}; }`);",[166,171,179,186,193],{"value":167,"source":93,"evidence":168},"jQuery",[169,170],{"id":96,"by":97,"text":98},{"id":112,"by":113,"text":114},{"value":172,"source":93,"evidence":173},"React",[174,175],{"id":96,"by":97,"text":98},{"id":176,"by":177,"text":178},"40916046","Justsignedup","I have to strongly agree with this. The entire point of react was to avoid all the challenges of old imperative coding of syncing up state with render state. The Dom digging was…",{"value":180,"source":93,"evidence":181},"SolidJS",[182],{"id":183,"by":184,"text":185},"40891350","udbhavs","> If we accept the fact that the web is inherently imperative, then I believe we can resolve most if not all of the above problems. We don't need to throw the baby out with the…",{"value":187,"source":93,"evidence":188},"Mithril",[189],{"id":190,"by":191,"text":192},"40915945","llimllib","Mithril seems like it can do something pretty similar: https:\u002F\u002Fmithril.js.org\u002Fjsx.html (Not trying to discourage you, just linking it)",{"value":194,"source":93,"evidence":195},"Google incremental-dom",[196],{"id":197,"by":198,"text":199},"40892321","jauco","This reminds me of google’s incremental dom (https:\u002F\u002Fgoogle.github.io\u002Fincremental-dom\u002F ) it surely made some things (like making sure an element has focus) a lot easier to do and…",{"comments":201,"answered":31,"key":202},21,[203,204,207],{"id":78,"text":79},{"id":205,"text":206},"40892130","\"greater power & greater responsibility\" is definitely the tradeoff I'm making. One of the tradeoffs I list in the readme is that you really need to think about the UI in a way…",{"id":208,"text":209},"40916324","Same, used jQuery for years and had a love\u002Fhate relationship with it. You're correct that React solved the imperative problems from before, but that's not the only factor to…",{"commenters":211,"max_depth":31,"maker_replies":201,"first_comment_mins":212,"lifespan_hours":213},23,237,119,[215,217,219,220,222,224,225,227,229,231,234,237,239,242,245,247,250,251,254,257,259,261,263,265,268,270,271,274,276,277,278,279,282,284,287,289,291,293,296,298,301,303,305,309,311,315,317,319,321,323,324,325,329],[96,32,30,216,97,32],"project\u002Fcritical\u002Fdesign",[78,32,32,218,11,30],"maker\u002Fneutral\u002Fnone",[124,32,30,216,97,32],[205,32,32,221,11,30],"project\u002Fneutral\u002Fdesign",[176,32,32,223,177,32],"commenter\u002Fneutral\u002Fnone",[208,32,32,223,11,30],[226,32,32,223,177,32],"40916424",[228,32,32,223,11,30],"40916691",[183,30,36,230,184,32],"project\u002Fneutral\u002Fidea",[232,30,32,233,11,30],"40891516","maker\u002Fneutral\u002Fidea",[116,235,30,236,117,32],2,"project\u002Fcritical\u002Fidea",[238,235,32,223,11,30],"40891656",[240,235,32,241,148,32],"40894099","other\u002Fneutral\u002Fnone",[243,235,32,223,244,32],"40891726","zarathustreal",[246,235,32,218,11,30],"40891842",[248,36,32,241,249,32],"40893006","peterleiser",[84,36,32,218,11,30],[252,36,32,241,253,32],"40916141","i_like_robots",[255,36,32,241,256,32],"40916579","cnity",[258,36,32,241,11,30],"40916658",[260,36,32,223,256,32],"40916681",[262,36,32,241,253,32],"40917429",[264,36,32,241,256,32],"40917537",[266,267,32,241,104,32],"40916351",4,[52,267,32,269,11,30],"project\u002Fpositive\u002Fidea",[103,267,32,223,104,32],[272,39,32,241,273,32],"40916169","breadwinner",[275,39,32,223,11,30],"40916672",[147,31,36,230,148,32],[49,31,32,269,11,30],[135,31,30,236,136,32],[280,31,32,223,281,32],"40916243","Spivak",[283,31,32,221,11,30],"40916601",[285,31,32,241,286,32],"40917435","WorldMaker",[288,31,32,241,136,32],"40919011",[290,31,32,241,286,32],"40922100",[197,292,39,269,198,32],7,[294,292,32,295,11,30],"40892468","commenter\u002Fpositive\u002Fnone",[155,297,36,230,156,32],8,[299,297,32,300,11,30],"40891501","project\u002Fneutral\u002Fexecution",[190,302,36,230,191,32],9,[304,302,32,223,11,30],"40916565",[306,307,30,216,308,32],"40916483",10,"spankalee",[310,307,32,221,11,30],"40916769",[312,313,36,230,314,32],"40916200",11,"padjo",[316,313,32,230,11,30],"40916466",[112,318,30,236,113,32],12,[320,318,32,223,11,30],"40919115",[322,318,32,223,113,32],"40935465",[162,33,36,230,163,32],[72,33,32,300,11,30],[326,327,32,241,328,32],"40891657",14,"darepublic",[330,327,32,241,11,30],"40891732",[],[333,338,343,347,352,356],{"id":334,"name":335,"points":336,"category":337},"40899242","Satyrn",611,"dev_tools",{"id":339,"name":340,"points":341,"category":342},"40902012","Sabby",561,"creative",{"id":344,"name":345,"points":346,"category":337},"40932492","Dut",396,{"id":348,"name":349,"points":350,"category":351},"40916326","BitWHIP",353,"infrastructure",{"id":353,"name":354,"points":355,"category":337},"40904862","Onlook",336,{"id":357,"name":358,"points":359,"category":360},"40881836","Telescope",273,"web_saas",false,"v2",{"id":364,"name":5,"line":6,"ai":361,"cat":19,"year":13,"points":14,"comments":15,"rec":27,"s":365,"top":14,"kw":366,"maker":11,"domain":10,"tier":18,"attempts":32,"strip":367,"url":9,"mix":368,"praise":92,"objection":108,"sub":20},40889951,-0.24,[23,24,25,26],"1010003010000000000003010005033013010300",[30,31,32,31],1793991095117]