HNNewShowAskJobs
Built with Tanstack Start
Marko – A declarative, HTML‑based language(markojs.com)
364 points by ulrischa 3 days ago | 183 comments
  • nolanl3 days ago

    As someone who has actually worked on JavaScript frameworks, I think Marko is criminally underrated. The compile-time optimizations are extremely impressive: https://markojs.com/docs/explanation/fine-grained-bundling

    I was not surprised for example that Marko came out very well in this performance comparison: https://www.lorenstew.art/blog/10-kanban-boards

    • CSSer3 days ago |parent

      I remain convinced that RSC and the SSR craze was a result of someone (or multiple) people needing a raise and their friends wanting to start a company selling abstract compute. Statically hydrated, minimal React was pretty great when served over good CDN infrastructure. Then I watched the bundle sizes and lock-in balloon. That second article is a dragon slayer. It really lays out the problem with React. In marrying itself to Next.js and embracing the server, it's betrayed the platform. Meanwhile, the platform itself has matured. React practically built my career, and I just don't have a reason to choose it anymore.

      • throwingrocks2 days ago |parent

        SSR isn’t a craze. Web applications have been served that way for literal decades now.

        • CSSera day ago |parent

          Read it in context. There's nothing wrong with SSR.

      • erikpukinskis2 days ago |parent

        I agree, if there is a death of React it will be killed by Next/Vercel.

        I probably shouldn’t care. I’m just not looking forward to the chaos of another full “turn” in JavaScript, akin to query->backbone or backbone->react.

        Maybe I shouldn’t fear it. I’ve just yet to see an idea that feels valuable enough to move an entire ecosystem. Svelte, HTMX, etc… where is the “disruptive” idea that could compel everyone to leave React?

    • brain_staple3 days ago |parent

      That’s interesting. I’ve always held SvelteKit in high regard for greenfield projects because it balances capability, developer experience, and performance, but I’ll have to give Marko a look. I’d love to see a similar deep dive into Electron style desktop frameworks since that space still feels underexplored compared to mobile. I honestly wouldn’t know where to start for a video game interface, and that bothers me.

  • tills133 days ago

    It looks interesting and in a past life I probably would have tried it out but do you know why I like React? Because it's just JavaScript.

    This `<let/variable=...>` and `<for ...>` syntax is awful.

    • afavour3 days ago |parent

      I mostly agree with you but React isn’t just JavaScript. JSX is not JavaScript. It’s just that we’re so used to it we don’t consider it notable any more. Worth keeping in mind when you’re looking at a brand new framework.

      • tshaddox3 days ago |parent

        There are a lot of things people might mean by claiming that something "is just JavaScript," but one possible meaning is that the source code you write can run in the browser without any build whatsoever. For React, that's true with the exception of JSX, which is a very simple and optional syntax transform. (Of course in practice you'll probably want to do module bundling too, but browsers could technically load your ES modules directly from static file storage.

        For Marko, that doesn't seem to be the case, but it also doesn't really make sense given the problems that Marko is trying to solve.

        Another thing people might mean by "it's just JavaScript" is a much more subjective notion about how similar the overal syntax, control flow, etc. feels to whatever previous JavaScript experience the person has. This meaning is a lot harder to pin down, and in most cases reasonable people could disagree on what is and isn't "just JavaScript" according to this meaning. That said, I would tend to agree that React's templating uses normal JavaScript control flow and composition primitives more so than Marko.

      • fouc3 days ago |parent

        Speaking of writing javascript instead of JSX, I'm a big fan of the hyperscript approach:

              var ListComponent = () => {
                let count = 0, selected = null
                return {
                  view: ({attrs: {items}}) =>
                    m("div", [
                      m("p", "Clicked: " + count + " times"),
                      m("ul", items.map(item =>
                        m("li", {
                          onclick: () => { count++; selected = item },
                          style: {cursor: "pointer", color: item === selected ? "blue" : "black"}
                        }, item)
                      )),
                      selected && m("p", "Selected: " + selected)
                    ])
                }
              }
        • dualogy3 days ago |parent

          > Speaking of writing javascript instead of JSX, I'm a big fan of the hyperscript approach

          Speaking of writing JS instead of JSX or your example, I like the vanjs.org approach:

              const Hello = () => div(
                p("Hello"),
                ul(
                  li("World"),
                  li(a({href: "https://vanjs.org/"}, "VanJS")),
                ),
              )
              van.add(document.body, Hello())
          • insin3 days ago |parent

            JSX was such a breath of fresh air after having written and maintained apps which used both of these formats for years (and also having written a library which supported both of them for reusing the same templates on the server and in the browser) - it's the commas! I'm glad it's everywhere now.

            But that was also back in the days when trailing commas at the end could break things, JavaScript editor support was relatively poor, and tooling wasn't where it is now (knowing your code is once again valid because the autoformatter just kicked in).

          • mb21003 days ago |parent

            Since we're sharing HTML in JS syntaxes. Don't forget JS tagged template literals like https://jsr.io/@mastrojs/mastro/doc/~/html

        • Rohansi3 days ago |parent

          This looks like what JSX compiles into. You can do the same (or similar) with React by using `React.createElement` instead of `m` (or just alias it) so you don't need JSX.

        • kevlened3 days ago |parent

          Your example template and the others here are almost jsx after it's compiled (handwritten below). This jsx discussion seems more about removing the compile step, which you can do with https://github.com/developit/htm

              import { createElement as m } from "your-jsx-compatible-library";
              
              var ListComponent = () => {
                let count = 0, selected = null;
                return {
                  view: ({ attrs: { items }}) =>
                    m("div", null,
                      m("p", null, "Clicked: " + count + " times"),
                      m("ul", null, items.map((item) =>
                        m("li", {
                          onclick: () => { count++; selected = item; },
                          style: { cursor: "pointer", color: item === selected ? "blue" : "black" },
                        }, item)
                      )),
                      selected && m("p", null, "Selected: " + selected)
                    )
                };
              };
        • lf-non3 days ago |parent

          Yes, I also like relying on just functions.

          I have found aberdeenjs a better dx than hyperscript.

          https://aberdeenjs.org/

          • aatd863 days ago |parent

            oh didn't know that one. Been building something that shares the same goals although I can see it is different in many ways. Interesting.

        • tills133 days ago |parent

          fwiw I think this is worse than Marko in terms of syntax and certainly in terms of readability. For all its flaws, HTML / XML / like syntax is such a good declarative way of writing UI imo. React would not be as popular as it is today were it not for JSX. Like the other reply to your comment said: this is effectively identical to what JSX compiles to assuming your jsxPragma is `m`

      • jbreckmckye3 days ago |parent

        It almost was JavaScript! ES4 was going to have something very similar to JSX tags. Well, an extension to ES4 called E4X

      • paulddraper3 days ago |parent

        It is thin syntax sugar.

          <MyComponent prop={value}></MyComponent>
        
        is just

          jsx(MyComponent, { prop: value })
        
        Libraries and apps can use JSX or JS syntax.
      • erikpukinskis3 days ago |parent

        I mean, you’re technically correct. But you’re also not understanding the point.

        What people mean when they say “React is just JavaScript” is…

        1) JSX, more than any other templating system, is just HTML interleaved with JavaScript. It’s HTML, and anything between { and } is evaluated as JavaScript.

        2) Inserting a React component’s “HTML tag” in your JSX is _actually_ the same as calling the JavaScript function. The HTML attributes are the function arguments. Yes, inside your function there can be state, and there can be contexts, and there are refs. But you get at all of those things by calling JavaScript functions.

        Like,

              <b><MyComponent attr=“yes” /></b>
        
        is literally identical to:

              <b>{MyComponent({ attr: “yes” })}</b>
        
        It’s the tiniest bit of syntactic sugar.

        I feel like too many people think “React is Just JavaScript” is some kind of lie people tell to make React sound cool.

        It’s not a lie. There’s a _small_ amount of hand waving around the word “just” but the point is, it’s WAY smaller than what you need to explain the ways Svelte or Vue or Angular diverge from plain JavaScript.

        • MrJohz3 days ago |parent

          It's further than that even. JSX has the semantics of (modulo a couple of optimisations there and there) a bunch of nested function calls returning normal JavaScript objects. That means you can, in your head, very easily convert between the JSX representation of an expression and the equivalent transpiled JavaScript code.

          This is unlike a lot of other templating languages where, even if the expression part of the language is pure JavaScript (or PHP or Python or whatever), it's still interleaved with arbitrary text which will get printed out according to its own rules. This makes the whole thing much harder to reason about (leading to the philosophy that you should put as little logic as possible in your templates because it makes them harder to understand, _even when that logic is directly related to the templating process_.

          A good example is for-loops. In a lot of templating languages, you start in text-land, then you enter expression-land to write the opening {% for (const X of ...) %} line, then you're back in text-land again. You sprinkle in a couple of expressions, and then at the end you go back to expression-land to close the loop. You're jumping backwards and forwards between the two worlds, but there's no real syntactical or structural support for mixing them.

          Meanwhile, in JSX, you start in text-land, then you open up an expression between two curly braces, and in that expression you write the entirety of your loop. If you need to go back to text-land within that loop, you can create a _new_ set of text nodes, but you're not interleaving expressions and text in the same way.

          The result of this is that, once you understand how your JSX will get compiled, it's very easy to read it as if it were the JavaScript that it will get compiled to, rather than as a separate templating language. Which in turn makes it very easy to think of it as "just JavaScript", even if it's technically a syntax extension.

        • csande173 days ago |parent

          I don't think the syntactic sugar works how you describe. JSX components actually desugar to something like:

             <b>{jsx(MyComponent, { attr: "yes" })</b>
          
          (Previously this function was called "React.createElement", but these days they have special functions that only the JSX compiler is allowed to use.) The extra layer of indirection is needed to do things like support hooks being called inside of MyComponent's function body, keep track of `key` props, and so on.
          • samdoesnothing3 days ago |parent

            I don't think that's true, you can write uncompiled createElement calls and everything still works fine.

            • csande173 days ago |parent

              createElement still exists, but the JSX compiler doesn't use it anymore; see https://legacy.reactjs.org/blog/2020/09/22/introducing-the-n...

              Regardless of whether you use JSX or createElement, you can't just call MyComponent({ attr: “yes” }) directly, is the main point.

              • samdoesnothing2 days ago |parent

                Yeah I don't think you ever could just call MyComponent(props) directly if the component used hooks. If it was hookless (what a concept...) it wouldn't matter.

              • christophilus2 days ago |parent

                You certainly can in Preact.

        • afavour3 days ago |parent

          > JSX, more than any other templating system, is just HTML interleaved with JavaScript. It’s HTML, and anything between { and } is evaluated as JavaScript.

          That’s not true though and IMO is one of the weaknesses of JSX: it looks like something it is not. Having to use className instead of class is one of the most obvious tells. But in theory if it was just HTML with {}s I should be able to do:

              <{tagName} />
          
              <span {someStringWithAttributes} />
          
              <div>{stringContainingHTML}</div>
          
          and many other things you’re actually not able to do. Not to mention that things like onClick aren’t actually HTML attributes and are instead event listeners, etc etc.

          Once you grasp that what you’re actually doing is a function call with an object of arguments it makes sense. But it isn’t HTML. It’s a chain of function calls.

          We’re all really used to it so we don’t think about it a lot. But I always try to remind myself of that when I look at a new unfamiliar syntax.

          (not to mention, your example isn’t correct! <Component/> don’t map to Component(), it maps to previouslyUnknownFunction(Component()), which is another confusing factor)

          • christophilus2 days ago |parent

            You can just use “class”, fyi, at least in Preact, and iirc, it works in React, but isn’t officially supported there.

        • dminik3 days ago |parent

          And this is one of the disadvantages of JSX. The snippets you posted are NOT identical.

          JSX (react flavor) is lazy. <My component> is not rendered/evaluated until it's needed.

          You can't just call a react component. It's not a regular function call.

        • zaidf3 days ago |parent

          It’s not JavaScript if you can’t make an html page locally and open it in your browser without things like an http server or need to transpile.

      • Latty3 days ago |parent

        You can use React with just JS, JSX isn't core to React. htm is a library that uses string templates and is just Javascript but works like JSX and can (but doesn't need to be) compiled down like it, and you can use with with React or other tooling.

      • ethanpil2 days ago |parent

        Another interesting approach IMHO is https://github.com/gnat/surreal

      • tills133 days ago |parent

        That's true, sure. My response to that is in React you have JavaScript & JSX and there are clear boundaries. It's not mixed. I don't write

        <for ...>

        In JSX I write JavaScript that returns JSX:

        {data.map(node => <Element {...node} />)}

        ^ ----- JS ----^ ^ ------ JSX -------^

        or

        const elements = data.map(node => <Element {...node} />) ... <div>{elements}</div>

        Really the most obscure syntax there is the splatting but it makes sense to you when you realize that JSX is just syntactic sugar for JS:

        data.map(node => React.createElement(Element, { ...node }))

        • phatskat3 days ago |parent

          I’ve never been a fan of JSX. I tried years ago and wasn’t super into it, and then Vue after that and found the syntax a lot easier on the mental model.

        • c-hendricks3 days ago |parent

          There are of course libraries that use JSX and have '<For>' components

    • notpushkin3 days ago |parent

      Agreed on the syntax part. We’ve had good syntax for templates before:

        <ul>
          {% for user in users %}
            <li>{{ user.firstName }}</li>
          {% endfor %}
        </ul>
      
      And we have good syntax for templates now:

        <ul>
          {#each users as user}
            <li>{user.firstName}</li>
          {/each}
        </ul>
      
      Why do we have to squish everything into HTML-like-but-not-quite blocks?

      But no, JSX isn’t that great either:

        <ul>
          {users.map(user => (
            <li>{user.firstName}</li>
          ))}
        </ul>
      • cubefox3 days ago |parent

        Why not use html/XML style syntax rather than mixing two syntax styles? For example, "{/each}" already looks like "</each>".

        • benrutter3 days ago |parent

          I guess the argument against would be that <element> designates an HTML "thing", i.e. some content for rendering.

          </each> is about control flow, so it's a conceptually different thing.

          I can't tell how convincing that argument is to be honest, and how much I'm just rationalising familiarity.

          • cubefox3 days ago |parent

            I think there isn't too large a gap between "wrap this stuff in a box and add a line break afterwards" and "repeat this stuff for each item".

            • naasking2 days ago |parent

              Generally for templating, you want a visual distinction between the control language and the target/rendered language, because they are two different things.

              Where they aren't two different things, you have some kind of component configuration language, like WPF on .NET. There is no control language, the instantiated components have behaviours and are responsible for any control logic, like rendering a list of items. This isn't a template language though.

              HTML now has web components and so you can think of it in the latter way. I'm not sure if anyone has take this approach though.

              • cubefox2 days ago |parent

                > Generally for templating, you want a visual distinction between the control language and the target/rendered language, because they are two different things.

                But as I just said, in the end their function actually doesn't seem overly different (to me at least) so a visual distinction with curly brackets rather than angle brackets is perhaps not necessary.

                • naasking2 days ago |parent

                  Languages are intended to be read more than written. You'll often be manually reading both the original source and the generated source and comparing them to ensure the original source is being correctly interpreted. Having those visual markers is very useful for debugging this process.

        • tannhaeuser3 days ago |parent

          The question is why developers even want to contaminate markup with programming constructs when they have already everything they could ask for, including an object literal syntax ("JSON") for arbitrary graphs that also can encode a DOM.

          SGML (XML, HTML) is for content (text) authors not developers, but webdevs just don't get it and look at it as a solution to developer problems.

          • mananaysiempre3 days ago |parent

            Because you need quasiquoting to construct trees decently, and JavaScript doesn’t have any worth a damn.

      • Already__Taken2 days ago |parent

        These aren't good because for 0-lists you have an empty parent containers so often you have a wrapping if outside all of that. More generally, template logic indent doubles up inside the indent levels of the template markup and I just find it ugly.

        I like vue a lot more;

            <ul v-if={users}>
              <li v-for={some in users}>{some.name}
            </ul>
        • notpushkin2 days ago |parent

          Agree with sibling comments on control flow vs elements separation. For your specific case though, I think a middle ground can be found here:

            <ul #if={users}>
              {#each users as user}
                <li>{user.name}</li>
              {/each}
            </ul>
    • jbreckmckye3 days ago |parent

      In a past life we did try it... Marko has been around for years.

      It started as a project at eBay and then got spun out to an open project around 2015

    • etothet3 days ago |parent

      To each their own. This syntax actially resonates with some people, which is why template-based frameworks like Vue and Svelte are also popular. In fact, at first glance this reminds me a lot Vue in some of its approach and syntax.

      BTW - with Vue you can use entirely JSX of you dislike HTML component syntax (I don’t know enough about Svelte to know if it allows the same).

      • prokopton3 days ago |parent

        Svelte does not allow that.

    • someguyiguess3 days ago |parent

      React has not been just JavaScript for a long time. The react DSL just keeps getting more and more bloated as they add more hooks for more and more edge cases (useFormStatus, useActionState, etc…). It’s becoming just another bloated mess now. And I used to love react! This looks promising though. The syntax looks very straightforward. Even though it’s not “just JavaScript” it is very easily understood by most programmers. I’ve glanced at it for all of 2 minutes and it all makes perfect sense. Functions look like functions. Variables look like variables. I think it looks cool!

    • moritzwarhier3 days ago |parent

      Really, this point can't be stated often enough.

      It was my reason for switching to React when I learned TypeScript after getting more into JS frameworks via Vue.JS.

      My starting point was Vue 2.7, and I started out using string templates haha :)

      Even wrote some reactive custom code (without Vue, just regular DOM code) in a customer widget that utilized Object.defineProperty et al, inspired by Vue.

      And today, while I'm using React at $job, I also think Vue 3 is probably a solid framework as well.

      Last time I checked, they improved on DX of their component and templating system. But I'm not even sure whether they still recommend the v-if etc helper tags.

      For what it's worth, even Vue 2 always also supported JSX and later TSX

      • 3 days ago |parent
        [deleted]
    • iammrpayments3 days ago |parent

      Do you really believe React is just javascript?

      • pwdisswordfishy3 days ago |parent

        React is "just JavaScript" that you have to write in a very particular way, which the language in no way helps you enforce, for otherwise your "web app" will misbehave is bizarre and confusing ways.

        • brazukadev3 days ago |parent

          There are no particular ways to code react where JSX is just JavaScript, it is not.

          • Etheryte3 days ago |parent

            React is not the same thing as JSX. You can use React without using JSX and you can also use JSX without using React. This argument makes no sense from the get go.

            • brazukadev3 days ago |parent

              It does not change the fact that JSX is not valid JavaScript and so 99.9% of React code is not valid JS.

    • DonnyV3 days ago |parent

      No Vue, is just JavaScript. React is JSX.

  • mcny3 days ago

    What I'm hoping to see in the future are:

    1. native support for all http verbs such as put and delete in html itself without relying on JavaScript

    2. sensible controls for drop down, select, multi select, date, time, datetime and so on without relying on any JavaScript

    3. Submitting a form and submitting actions without reloading the whole page again without requiring any JavaScript

    4. A whole lot of stuff yes without requiring any JavaScript

    When I first heard the term htmx, I thought that was what htmx was but sadly it is just intercooler. What I am asking for requires broad support from browser vendors.

    • recursivedoubts3 days ago |parent

      We are working to integrated some of the ideas of htmx directly into the HTML specification:

      https://alexanderpetros.com/triptych/

      • mcny2 days ago |parent

        Thank you so much for doing this. I love it!

  • promiseofbeans3 days ago

    This is actually quite cool - JS inside HTML, rather than the more React-y HTML inside JS.

    As I understand it, Ryan Carniato was a major part of this project, and later went on to lead SolidJS, which goes back to the React style HTML in JS. Has he spoken at all about why he went back to that templating style?

    • mlrawlings3 days ago |parent

      Ryan was working on Solid before he joined eBay/Marko. Both projects have benefited from the shared knowledge and approaching a similar solution space from different angles.

      He eventually got the opportunity to work on Solid in a more full-time capacity and decided to take it, but still talks with the Marko team from time to time

    • sorrythanks3 days ago |parent

      Yes. Mostly because:

      • JSX is well understood by a lot of developers • support is already built in to text editors • it is understood by typescript

    • bitwize3 days ago |parent

      JS inside HTML! Groundbreaking! It's nothing like Netscape ever conceived in 1995...

  • abraxas3 days ago

    After two decades of this churn we are back to the equivalent of JSP. It was the correct paradigm all along but millennials wouldn't be caught dead working with such a "lame" technology so they bestowed SPA on us and now they are slowly walking it back.

    • woleium3 days ago |parent

      Yes, we go in circles, but there are subtle (and sometimes not so subtle) improvements every iteration. Of course sometimes there are also dead ends.

      It is exciting to see what the ingenuity of the next group brings, even though some existing things are lost, but hopefully not forgotten.

      • epolanski3 days ago |parent

        This.

        Also it cannot be understated: apis, language and tooling are miles ahead better they were a decade ago or more.

        • ricardobeat3 days ago |parent

          I’m not completely sure of that. The simplicity of a backbone app, plain javascript with no build, less/sass, early days node.js or old RoR apps is becoming increasingly elusive. Not a lot of modern apps you couldn’t build with those stacks, and most of the underlying technology is the same (http/html/css/js/sql/libuv/etc).

          Saying this feels like advocating for a return to horse carriages though, when the right analogy would be the brief electric car era of the early 1900s, and React as the Model T.

          • christophilus2 days ago |parent

            Ooof. No thanks. SASS can die a fiery death, and give me React over Backbone 10 times out of 10. I guess these things are somewhat subjective, but I don’t miss the pre-React days at all.

    • gf0003 days ago |parent

      We also had JSF, which was even cooler - being able to reconstruct the state server-side. It was ridiculously fast to write complex form-driver websites with that! No DTOs/schemas in different languages, no worry about how the client calls the server, what happens if it fails, etc.

      The only problem is that it won't necessarily scale to some insane numbers without some care.

      (Not sure why the past tense, it does work and developed still)

    • mexicocitinluez3 days ago |parent

      > It was the correct paradigm all along but millennials wouldn't be caught dead working with such a "lame" technology so they bestowed SPA on us and now they are slowly walking it back.

      Oh man, I wish people would stop attributing picking SPA's to not wanting to use "lame" technology. It makes them sound myopic and naive. Really naive.

      You may not have been around at the time, but I certainly was. And the idea that SPAs don't (or didn't) have their place is just plain absurd.

      Like "Tell me you're a backend dev who is made they have to learn new stuff to stay current" without telling me.

      In fact, I'm not even sure what your argument actually is. Is it MSP vs SPA? Is it JSP vs any of the other backend languages you can still use with React? Is it templates vs JSX? What are you actually trying to argue?

      Are your rose-colored glasses ignoring what a pain a decent UX was to build in those technologies? That mobile apps pushed backends to an api-only version and SPAs took over for the frontend? Are you saying people should pick old technologies wtih old tooling just because you didn't get on board with it the first time?

      It's not swinging back to JSP, it's finding a middle-ground between the 2. THAT'S what progress is.

    • Jenk3 days ago |parent

      > It was the correct paradigm all along

      Debateable.

    • someguyiguess3 days ago |parent

      I’d venture to say that the idea of a “correct paradigm” is based on a false premise. Why would there be one paradigm to rule them all? Maybe there is more nuance. Maybe certain paradigms are better for certain applications.

      • notnullorvoid3 days ago |parent

        I'd go a bit further and say certain paradigms may be better for certain people.

  • croisillon3 days ago

    previously:

    January 2023, 125 comments - https://news.ycombinator.com/item?id=34591625

    August 2017, 150 comments - https://news.ycombinator.com/item?id=15057371

    February 2015, 10 comments - https://news.ycombinator.com/item?id=9065447

    • joshdavham3 days ago |parent

      Oh wow! So I guess Marko has been around for while. Despite that, this is my first time hearing about it.

      • ricardobeat3 days ago |parent

        The main author also wrote morphdom circa 2015, which is/was used in htmx and sprung up a bunch of other frameworks.

  • ccpzza3 days ago

    For those curious, the Marko team created a HN clone to showcase Marko 6

    https://github.com/marko-js/example-hacker-news

  • lf-non3 days ago

    This looks interesting and seems like a vast improvement over jsx.

    I especially love the pug style concise syntax which for some reason they have buried deep into the docs rather than showcasing front and center.

    https://markojs.com/docs/reference/concise-syntax

    • skrebbel3 days ago |parent

      I dunno, to me that seems like all YAML's mistakes all over again. I quite like the conciseness, and significant whitespace seems like a good match here, but the double hyphen thing really seems odd to me. And the syntax is so hard to parse, apparently, that their own example is syntax highlighted incorrect, coloring content as if it's tags.

      • piercey42 days ago |parent

        FYI in an actual editor the syntax highlighting works. In the (new) website it's using a different highlighter which has issues. Will be fixed soon!

        • skrebbel2 days ago |parent

          Cool!

          If I may ask, what made you settle on the double dash to disambiguate content from tags? Like is it some sort of nod to SGML from way back when? It seems like an odd choice to me at first glance, but I bet it was thought about long and hard so I’d love to hear some background about what alternatives you considered.

    • sings3 days ago |parent

      I was looking at Marko a few years ago because of the concise syntax. I have always thought highly of Pug and would have loved a framework that integrated that sort of elegant, minimal syntax. Unfortunately, Marko doesn’t even get the syntax highlighting right in its own docs for this style.

      The example on that page with leading commas to separate tag attributes, and a number of other choices across the framework are also a turn off for me personally.

      I’ve mostly been using Svelte for the past half-decade instead but still hope for something more elegant to come along.

  • hyperhello3 days ago

    The problem when taking several languages and mixing them together this way is that the result is supposed to have brevity, but it’s actually unreadable. You need slash to mean something grammatical, colon has to say something, you can speak “open brace” in a way that anticipates; @ means “at”. This code looks more like a compression scheme.

    • gdotdesign3 days ago |parent

      I think I managed to combine three languages in one with Mint (https://mint-lang.com/):

      1. There is HTML (tags) with, but without interpolation {...} you can put string literals, variables and everything that type checks as HTML children.

      2. There is CSS but only in style blocks where you can interpolate any expression you need and put in if and case expressions too.

      3. There is the normal Mint code you write the logic in (this would be the JavaScript in other languages).

      Here is an example which have all three: https://mint-lang.com/examples/7guis/flight-booker

      The challenge was to make it seamless enough that so it doesn't look like that we tried to mash languages up, but to make them form a different language that is consistent and simple at the same time.

      • promiseofbeans3 days ago |parent

        Your Mint language looks awesome! You’ve done a great job making it very seamless between the 3 languages. I had a couple thoughts regarding your css/styling though:

        1. The one feature I prefer in Marko when compared to Mint is Marko’s nice ID and class syntax, rather than your custom selectors, so you can just use regular CSS (which seems to be advancing faster than the JS & HTML specs combined). You could get the scoping using shadow roots for your components (I’m sure this has flow on consequences, but given you own the language it’s probably better case than many others.)

        2. Interpolating values directly in CSS blocks is something that a lot of HTML templating systems sort of give up on (see Astro going out of it’s way to make interpolating variables super verbose [0]), so I’m glad to see you do it. Does the value interpolation compile to CSS variables that are set on the component root (or somewhere else I suppose) as in Astro [0], or is it just simple interpolation? Additionally, I can’t help but notice your hash symbol would conflict with ID selectors, so is CSS nesting available?

        Please don’t take this as criticism! I really like what you’ve done here and am very curious.

        [0]: https://docs.astro.build/en/guides/styling/#css-variables

        • gdotdesign3 days ago |parent

          1. Inside style blocks it's pretty much regular CSS except for interpolation and if/case expressions, so you can create a style for the root element and then use ids and classes if you desire, but it won't be optimized.

          2. CSS definitions without interpolation compile down to static CSS while the ones with interpolation compile down to CSS variables which are set on the element where the style is assigned. This also allows for passig arguments to styles [0].

          CSS nesting is supported and the interpolation doesn't conflict with the id selectors because interpolation is not supported in selectors.

          [0]: https://mint-lang.com/reference/styling/arguments

      • moron4hire3 days ago |parent

        It's there a way to define routes in a nested, hierarchial fashion, preferably across multiple modules?

        For example, with react-router, my root route object array I define by spreading out other route object arrays that I've imported from other modules in my project. And each of those do the same thing, recurring as necessary until I get to the full depth of my route tree.

        • gdotdesign3 days ago |parent

          No it's nor supported currently.

    • zupa-hu3 days ago |parent

      Isn't syntax pretty much just compression? We could write down the AST itself in some generic notation but that would be orders of magnitudes larger, so invent clever tricks to compress it, which we call syntax.

      Edit: typo

    • sorrythanks3 days ago |parent

      almost all code looks like nonsense when you're unfamiliar with it

  • hansvm3 days ago

    I don't normally comment on formatting, but for a language I assume they're dog-fooding for the demo it's amusing that none of the gradient-backgrounded text renders visibly ("HTML-based", "building web apps", etc).

  • faldor203 days ago

    I think it's worth noting Marko's proven nature.

    In years of using eBay, have never had an issue with it. Sad that that's a high praise these days, but it is. eBay is fast, it works damn well, and always has.

    As a counter point, React's poster children, in messenger, Facebook and Instagram. Have all been plagued with UI bugs for the entire time I've used them.

    Obviously those aren't wholly comparable, but I do think it's worth taking note of the actual outcomes we have when tools are used at real scale.

  • afavour3 days ago

    Maybe just me but I actually think building web apps is already fun. I’ve got a hot reloading instant dev environment, I can publish to users in an instant… it’s great!

    Looking at the Marko examples I feel the same way I do whenever similar stuff gets showcased: it’s trying to focus too hard on brevity and/or cutesiness and doesn’t seem like it would scale well to a full, complex web app. But maybe it’s not supposed to and maybe that’s fine.

    React and Svelte and the rest can read clunkily at times but they have a clear separation of concerns and I’m glad for that.

    • nchmy3 days ago |parent

      FWIW, marko comes from Ebay. So, it scales - and being primarily SSR, its a better UX than your preferred frameworks

      • marginalia_nu3 days ago |parent

        HTML rendering is, to be fair, not usually where you find the scaling issues.

      • afavour3 days ago |parent

        Pretty much every JS framework has SSR, the question is really how quickly does it hydrate. React typically rates poorly there but Svelte does great, at least partially because it has a compiler to optimize (like Marko does, it appears).

        • eyelidlessness3 days ago |parent

          Marko’s compiler is designed for partial hydration (by default, without any special developer effort), which performs quite well. IIRC they were also looking at implementing “resumability” (term coined by Qwik, for an approach that sidesteps hydration as a concept entirely). I’m not sure where they’re at on that now, but I think it’s generally safe to say that Marko prioritizes load time performance more than nearly all other frameworks.

          • mpeg21 hours ago |parent

            marko5 which is the stable version does partial hydration by default (like Astro, but with automatic boundaries)

            marko6 which is currently in public beta is resumable by default, and does some similar things to the also public beta qwik2

        • nchmy3 days ago |parent

          Marko did ssr by default, a decade before the other frameworks decided to bolt-on ssr...

        • hlimas3 days ago |parent

          [dead]

    • halapro3 days ago |parent

      React has a clear separation of concern? Excuse me? I only see do-it-all pre-styled components in the real world.

  • cubefox3 days ago

    It's misleading to call this "A declarative, HTML‑based language" when it in fact relies heavily on writing explicit JavaScript (which is very different from HTML and not declarative at all).

    Something like htmx does come a lot closer to being a HTML‑based language in my opinion. So much so that you could add it to the actual HTML spec.

    (That's not to say that Marko is bad, just that it's more a way to mix HTML and JavaScript in a more intuitive way rather than a declarative, HTML‑based language.)

  • brianzelip3 days ago

    Here’s an informing recent DevTools podcast episode featuring someone from the Marko team, https://www.devtools.fm/episode/

    • jt21903 days ago |parent

      Some interesting context from the podcast:

      > A lot of people are coming to eBay from a link that someone shared or from a search engine... This whole "amortized cost savings" you get from a Single-Page App (SPA) you don't necessarily get with eBay. Or people might go to eBay and open up ten [browser] tabs... If that's ten SPAs you're opening you're not really saving that much.

      > At the same time in 2012 people are coming out with React, Angular... the question was "can we just use these tools?" and the answer was "kinda no"... Initially React was considered but the things we needed right out of the gate was streaming [sending as much HTML as... available without waiting for services responding with loaded data for the specific page]... With streaming you can send out stuff to the browser and have the browser [start] showing content to user without having to wait for your slowest service. At eBay there are a lot of services... Essentially if we were to adopt React or Angular the fact that there wasn't streaming would essentially mean that we're throwing away two seconds or so... which is not acceptable.

    • quest883 days ago |parent

      404

      • brianzelip3 days ago |parent

        Oops!

        https://www.devtools.fm/episode/146

  • jordanscales3 days ago

    Looks absurd. Can't wait to try it.

  • 3 days ago
    [deleted]
  • andix3 days ago

    I didn't look deep into Marko yet, but in my opinion JSX is by far the best HTML template language there is. And it's not restricted to React.

    Most other template languages hits serious limitations really fast. I tried and hated (for non trivial things): Angular, Handlebars, Razor (dotnet) and Vue (which does support JSX optionally).

    • Rendello3 days ago |parent

      I've been liking the model of the Python library Dominate [1]. You write your HTML as regular Python code, and you render() once at the end, having full control over the formatting. Well, at least in theory; in practice the formatting is brittle and the library otherwise makes some choices I don't like.

      I wrote a Rust library with a more restricted/verbose API, and I've been enjoying using that. Unfortunately, I find it really hard to make it as fast as I want. It's really the perfect use case for arena allocation, but doing that and keeping the API as function calls mirroring HTML is not trivial, and probably requires macros to rewrite the tree as a series of stack pushes.

      1. https://pypi.org/project/dominate/

    • 3 days ago |parent
      [deleted]
    • joshdavham3 days ago |parent

      Could you please try to be a bit more substantive with your comments?

      E.g., Why do you think JSX is the best? What limitations did you hit with those other template languages?

      • andix3 days ago |parent

        Most template languages can't do something like that:

          // data
          const numbered = true // or false
          const strings = ["a", "b", "c"]
        
          // render
          const items = strings.map(i => <li key={i}>Item {i}</li>)
        
          if (numbered)
            return (<ol>{items}</ol>)
          else
            return (<ul>{items}</ul>)
        • piercey43 days ago |parent

          Marko can! It's "define" tag lets you create reusable templates in your reusable templates.

          https://markojs.com/docs/reference/core-tag#define

        • gigatree3 days ago |parent

          RippleJS is doing the same sort of thing, but better IMO

    • epolanski3 days ago |parent

      I written lots of Vue/angular/react (like more than 3 major projects with each) and I'm a firm believer that:

      1. Jsx is nicer to write but that's a non issue

      2. vue's and angular's directives and bindings lend themselves to much saner and lighter rendering (performance does matter)

      3. Vue is much easier to tame, it's reactivity model does not require a PhD in hooks or a deep understanding of React's internals. It just works out of the box as it should and is much easier to control the rendering lifecycle.

      At the end of the day, after many years, my preference goes with Vue and Nuxt especially which is tremendously better than the monsters of Next or RR. That's what pays the bill the easiest and is eventually easier to maintain and optimize.

    • mock-possum3 days ago |parent

      Have you ever given lit html a whirl?

  • nielsbot3 days ago

    Maybe off topic, but I’d kill for a HAML for TSX or Svelte!

    Working with HAML really did make building web app fun IMO. I can’t be the only one!

    • ALLTaken3 days ago |parent

      Someone posted here, thanks for that!! It immediately reminded me of HAML: https://harcstack.org/

      I like HAML a lot, it was the most pleasant to develop with. And it shares a lot in common with Stylus. They both shared things in common.

      NO NEED FOR: Curly braces, parentheses and semicolons. The cool thing, it was all optional and I wasn't forced to make use of all shortcuts!

      I developed my own CSS Framework in 2003, shared with some UX guy at Yahoo, who incorporated it into YUI mostly as is, after I waived all rights. Most of that became internet standard. Later I had my own PHP based CSS scaffolding framework in 2005 that could also generate grids (before flex-box). SCASS/LESS was really similar to my framework, when it came out.

      But I disliked it, it just looked like PHP mixed with CSS. I thought why accept the ugly syntax, despite a compiler being available?

      The best ever existed is: HAML + Stylus + (HARC?)

      See the beauty of it: https://stylus-lang.com/docs/selectors.html

      Now compare with HAML https://haml.info/

      I think https://harcstack.org/ makes a good successor.

    • braebo3 days ago |parent

      Svelte already has a Pug preprocessor :)

      I used to use it years ago. So much nicer than HTML.

    • rk063 days ago |parent

      vue allows other languages in .vue files for both css & html similar to js

  • shevy-java3 days ago

        <p>Today is ${new Date().toDateString()}</p>
        <p>Random number: ${Math.floor(Math.random() * 100)}</p>
    
    Sorry, I don't like it. I already disliked that immensely in PHP. Not going back to that spaghetti mesh-up.

    The intro is also incorrect in my opinion. It writes a "HTML-based language", but this is more a hybrid of HTML and JavaScript. Why is JavaScript not mentioned in the intro?

    • librasteve3 days ago |parent

        p “Today is {Date.today}”,
        p “Random number: {(^100).pick}”
      
      Thought I would share this example as written in Raku using https://harcstack.org
    • someothherguyy3 days ago |parent

      > I already disliked that immensely in PHP. Not going back to that spaghetti mesh-up.

      That looks like a pretty normal template to me and nothing like plain PHP templates? What do you mean by "spaghetti mesh-up"?

    • Lerc3 days ago |parent

      Is there any significant difference between that and

          element.innerHTML=`
            <p>Today is ${new Date().toDateString()}</p>
            <p>Random number: ${Math.floor(Math.random() * 100)}</p>
          `
      
      (ideally .setHTML() when it's available)

      At that point I think I'd have a skeleton html file that fetches a JS that does it all. I'd take JS with embedded HTML over HTML with embedded JS.

      • TheCraiggers3 days ago |parent

        Isn't it wonderful that we live in a world where both ways can exist together, along with a myriad of other ideas for how to do the exact same thing?

        • Kiro3 days ago |parent

          The point is that both ways contain the same "spaghetti" that the OP is complaining about and that it's unclear what alternative they actually prefer.

      • worik3 days ago |parent

        No.

        But you can write dreadful code in any language

    • marcelr3 days ago |parent

      this comment really proves that people do not consider the information presented to them

      marko is not comparable to php

      it is much closer to svelte

      i used to sympathize with people complaining about js-fatigue, but at some point its a skill issue

      • jdmoreira3 days ago |parent

        Marko is server side. How is that closer to svelte?

        • swiftcoder3 days ago |parent

          Svelte can also be used for SSR

    • cco3 days ago |parent

      How would you prefer to write those examples?

      • didibus3 days ago |parent

        Separate templating from computing I'd assume.

      • ethmarks3 days ago |parent

        Personally, I'd either just put the content in an ID-ed span and have a script to replace the content. Another, perhaps better, way is to use Alpine.JS which excels at this kind of stuff.

        • ggregoire3 days ago |parent

          > I'd either just put the content in an ID-ed span and have a script to replace the content

          And so your script is broken when someone else in your team (or maybe even yourself) renames or removes the ID and forgets to search in the whole project if some piece of code depends on this ID. JSX fixed all that mess 10+ years ago.

          • cluckindan3 days ago |parent

            Yet you still need IDs for ARIA attributes, so now the JSX also needs a pile of shared variables

        • ghurtado3 days ago |parent

          Either solution sounds more verbose than the example and require writing code in at least one other source file

          • nine_k3 days ago |parent

            But that separation is sometimes the point. A designer tweaking the looks has no chance to break the computation logic, and an engineer tweaking the computation part won't disrupt the design by mistake.

            Terseness is good for code golf [1]. I disliked CoffeeScript after writing it for some time: nearly any typo can result in another syntactically correct program which, of course, does not what you wanted the original program to do, or fails the compilation in an unrelated place. A practical language has safety margins, aka some redundancy.

            [1]: https://en.wikipedia.org/wiki/Code_golf#Dedicated_golfing_la...

            • sorrythanks3 days ago |parent

              Unless the designer removes the id, or the engineer introduces new output that is not styled.

          • ethmarks3 days ago |parent

            But they're both framework-agnostic.

            This snippet works with any framework and any build step.

              <script src="https://unpkg.com/alpinejs@3.x.x/dist/cdn.min.js" defer></script>
              <div x-data="{ 
                today: new Date().toDateString(),
                randomNum: Math.floor(Math.random() \* 100)
              }">
                <p>Today is <span x-text="today"></span></p>
                <p>Random number: <span x-text="randomNum"></span></p>
              </div>
            
            I'll concede that Alpine.js is harder to understand and more verbose than Marko's syntax, but in order to use Marko you have to commit to the Marko framework. If you're willing to choose a framework solely for its JS-in-HTML capabilities, there are much better choices (like SvelteKit that handles JS-in-HTML wonderfully).
            • ffsm83 days ago |parent

              Fwiw, Marko predates svelte quiet significantly.

              It was originally created by eBay iirc, back in 2014 or so.

              It's syntax was even stranger back then, like writing "h1.myClass my header" to create a <h1 classes=myClass>my header</h1> and similar

        • mpeg3 days ago |parent

          You should give this a read, it explains why they chose to put everything within the markup

          https://markojs.com/docs/explanation/separation-of-concerns

        • huflungdung3 days ago |parent

          [dead]

    • cyanydeez3 days ago |parent

      Don't blame Marko for this type of abomination. This is basically fancy react JSX.

      ITS just bizzare people want to parse JavaScript at the same instance they're parsing html.

      Also, LLMs are going to destroy any new framework. Someone's gonna need to figure out how to integrate these things into new tools. LLMs suck but it'll be much worse if they freeze innovations cause they're too expensive to chase the new hotness.

      • whatshisface3 days ago |parent

        LLMs can make use of documentation and example code.

        • croes3 days ago |parent

          But because of LLMs there will be less example code

        • cyanydeez3 days ago |parent

          Yes. I understand second order context pollution.

      • Kiro3 days ago |parent

        You two are complaining about different things. Note how the parent mentioned PHP as the reference.

        • jamal-kumar3 days ago |parent

          I think the grand takeaway is that people like to complain

  • yilugurlu3 days ago

    It reminded me of ColdFusion, which could be something better if it hadn't ended up in Adobe's hands.

  • pier253 days ago

    This sort of stuff is just a big nope:

        <let/count=0>
    
    Why make a special language? Just use HTML and TypeScript that will be compatible with editors, tooling, etc. This is the same mistake Imba made.

    It's a shame because the core of Marko looks phenomenal: streaming, fine-grained bundling, rendering performance, etc.

    Also not sure about the file-based routing of Marko Run. That was a big reason why I abandoned SvelteKit.

    • Etheryte3 days ago |parent

      File-based routing is fundamentally flawed and it cannot be fixed. A number of libraries opt for it since it's easier for newcomers to pick up, but eventually you run into all of the cases where you do need something else. This in turn leads you to a hybrid system of multiple things where there's no single source of truth and everything is spaghetti.

      • epolanski3 days ago |parent

        Care to make quite a simple example where file based routing would struggle?

        • Etheryte3 days ago |parent

          Role based access control is one of the simplest examples, your routes need to be conditional and all come with related metadata for permissions and such. With file-based routing you'll then end up with your routes defined in one place and the configuration for them either in a separate different place or split up across the codebase. Whenever you need to change something you need to remember to do it everywhere else. If your routing is in code, you can define everything in one place with strict type checks, tests, and so on.

    • Too3 days ago |parent

      Let’s not pretend that useState() is plain TypeScript either. It’s a DSL in disguise.

      JSX is amazing for stateless rendering of templates. Not so much for state management. That should really have been given a dedicated DSL. Here I think Marko did the right thing, why they then made even for-loops a dsl is more questionable.

  • AbstractH243 days ago

    There’s some joke here about how that’s in contrast to Marketo…

    • celsius14143 days ago |parent

      There’s a Marko Pollo joke, too, but I’m too chicken to say it.

  • ifh-hn3 days ago

    I wonder how this compares to htmx, seems similar though obviously different in terms of approach. I'm getting a little jQuery feels too.

  • didip3 days ago

    Honestly, why not just put Scheme on the browser.

    Scheme is capable to represent HTML JS and CSS all in 1 language.

  • mobeigi3 days ago

    I love the landing page for this project. It's very engaging.

  • Antwan3 days ago

    The new jquery? Eurk.

    • austin-cheney3 days ago |parent

      I thought React was the new jquery.

  • senfiaj3 days ago

    Honestly I don't know... I'm somewhat skeptical about these "next big thing that will fix all your pains in web development". There is so much fragmentation in JS libraries / frameworks. Angular, React, Vue, Svelte, Asto, SolidJS, NextJS, Nuxt, Qwik... The list is so overwhelming. Almost each one claims that it fixes a problem in other framework, and a year later the other framework fixes that issue... I think it's better to stick to a big old player, such as Angular.

    • mlrawlings3 days ago |parent

      Marko has been around for over a decade at this point and powers most of eBay. It's not the oldest or the largest, but it's got a pretty solid track record

      • agos3 days ago |parent

        is there a second app interesting app written with it? what is the sentiment about Marko from the people who use it everyday?

    • nilslindemann3 days ago |parent

      Honestly I don't know... I'm somewhat skeptical about these "next big thing that will fix all your pains in web development". There is so much fragmentation in JS libraries / frameworks. Angular, React, Vue, Angular, Asto, SolidJS, NextJS, Nuxt, Qwik... The list is so overwhelming. Almost each one claims that it fixes a problem in other framework, a year later the other framework fixes an issue... I think it's better to stick to a big old player, such as Svelte.

      • senfiaj3 days ago |parent

        Svelte / SvelteKit is very lightweight but probably not a good choice if your app quickly grows in complexity. Angular has a larger community, long term support from Google, more people are familiar with, has rich functionality (including forms, localizations) and is well structured for huge projects. Once NextJS, SolidJS and others were interesting because of SSR, but Angular added this too (and continues to improve) in the recent versions.

      • nilslindemann3 days ago |parent

        No, just kidding. I believe in progressive enhancement, and none of these does this very well.

  • jm43 days ago

    It looks like they reinvented ColdFusion for modern web apps.

  • debuggerpk3 days ago

    abomination

  • bdcravens3 days ago

    So .... ColdFusion?

  • mattw13 days ago

    Dear front end devs

    Please chill w making new languages and frameworks that re-solve solved problems. The internet is working fine as it is.

    Warmest regards, Matt

    • rvzx3 days ago |parent

      Matt,

      Marko was created over a decade ago at Ebay.

      One of its core dependencies is morphdom, which has been used successfully by a slew of frontend view libraries like Marko, including Phoenix LiveView.

      Please chill. In general.

      Use cases are not all equivalent.

      Ignorance is boring.

      • mattw13 days ago |parent

        Nope. They are pretty much all equivalent. Browsers render HTML. This is a quite-solved-problem. Is there a scenario that can't be handled by the tools we've had for years? The web just doesnt require another paradigm. There is way, way too much tooling for a not-that-complicated problem.

        Also... if Marko 10 years old, where's the news part here?

        https://news.ycombinator.com/item?id=34591625

        Same post, in fact they are having the same argument we're having. At least the bloat is consistent.

        • rvzx2 days ago |parent

          > Nope. They are pretty much all equivalent.

          Good luck, man.

  • rapish623 days ago

    [dead]

  • wauwboer3 days ago

    [flagged]

    • ethmarks3 days ago |parent

      hello!

  • fuman3 days ago

    [flagged]

  • davexunit3 days ago

    I personally do not want to write HTML and I especially do not want to encode logic into it. This wave of HTMX-likes has some interesting ideas but encoding it all into HTML just feels so wrong to me. JSX is likewise awful. We need real programming languages here.