# Announcing elm-spa: version 6.0.0 🎉!

**URL:** <https://discourse.elm-lang.org/t/announcing-elm-spa-version-6-0-0/7299>\
**Category:** Show and Tell\
**Created:** [April 27, 2021, 8:35am UTC](https://discourse.elm-lang.org/t/announcing-elm-spa-version-6-0-0/7299 "2021-04-27T08:35:10Z")\
**Posts on this page:** 18\
**Page:** 1

<div class="post-metadata">

**Author:** ![RyanNHG](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/ryannhg/32/5162_2.png) [@RyanNHG](https://discourse.elm-lang.org/u/RyanNHG)\
**Post date:** [April 27, 2021, 8:35am UTC](https://discourse.elm-lang.org/t/announcing-elm-spa-version-6-0-0/7299/1 "2021-04-27T08:35:11Z")

</div>

# Hey, folks! 👋

I’ve got some exciting news to announce:

**The latest version of elm-spa has just been released!** 🎉

[![The new elm-spa homepage](https://elm-spa.dev/content/images/this-site.png)](https://elm-spa.dev)

# Why use elm-spa?

If you’ve ever glanced at a previous version of elm-spa and thought **“uhhh… maybe later”** : I _strongly_ encourage you to check out this latest design!

I think you’ll be delightfully surpised by how far the project has come along!

## A focus on welcoming beginners

The JS ecosystem has amazing projects like _Vue’s Nuxt.js_ or _React’s Next.js_. These projects make it easy to build an app from scratch, and provide conventions for newcomers to follow.

One of my **biggest** design goals for the latest release was to make it easy for new folks to get started. You can get a project spun up in a single command!

Even better, it only creates **three** new files:

1. An `elm.json`
2. A `public/index.html` entrypoint
3. This elm file:

```elm
module Pages.Home_ exposing (view)

import Browser
import Html

view : Browser.Document msg
view =
    { title = "Homepage"
    , body = [Html.text "Hello, world!"]
    }

```

The **elm-spa** CLI takes care of all the extra boilerplate for you! ✨

The CLI also comes with a built-in dev server, kinda like `elm reactor` for single page apps!

## Features

- **Automatic routing** - elm-spa generates URL parsers and page boilerplate for you under the hood
- **User authentication** - The new `Auth.elm` file makes it easy to guarantee only signed-in users have access to certain pages
- **Zero configuration CLI** - The CLI has been slimmed down and comes with its own dev server, build commands, and scaffolding tools. ( Also designed to play well with other dev servers )
- **That website tho** - The latest website has plenty of guides and examples to get you started with your next single page application!

### Should I upgrade from v5?

> “Oh heck yeck!” - my _(totally unbiased)_ advice

Here are a few reasons to upgrade:

- User authentication is no longer spooky
- Easier API for sharing state across pages
- Easier to work with elm-program-test and elm-test
- Less boilerplate all round!

You should take a look at this [RealWorld example app PR](https://github.com/ryannhg/elm-spa-realworld/pull/2) where I completely upgraded from elm-spa@5 in less than an hour. I just followed those friendly Elm compiler messages to victory! 💪

## Try it out, share those feels!

I’ve been iterating on the design for v6 for a while, and would love to hear your initial thoughts and impressions on how easy it was for you to get started.

### Helpful links:

- [Official website](https://elm-spa.dev)
- [GitHub repo](https://github.com/ryannhg/elm-spa)
- [NPM package](https://www.npmjs.com/package/elm-spa)

### Thanks for reading!

Ryan

---

<div class="post-metadata">

**Author:** ![nathanbraun](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/nathanbraun/32/3834_2.png) [@nathanbraun](https://discourse.elm-lang.org/u/nathanbraun)\
**Post date:** [April 27, 2021, 2:15pm UTC](https://discourse.elm-lang.org/t/announcing-elm-spa-version-6-0-0/7299/2 "2021-04-27T14:15:32Z")

</div>

Awesome, been eagerly anticipating this this! Congrats on the release!

---

<div class="post-metadata">

**Author:** ![nil](https://avatars.discourse-cdn.com/v4/letter/n/a183cd/32.png) [@nil](https://discourse.elm-lang.org/u/nil)\
**Post date:** [April 27, 2021, 2:44pm UTC](https://discourse.elm-lang.org/t/announcing-elm-spa-version-6-0-0/7299/3 "2021-04-27T14:44:57Z")

</div>

Looks great!

I would suggest promoting the release in the Github Releases section of the repo, as the “latest release” there is an old tag. [Releases · ryannhg/elm-spa · GitHub](https://github.com/ryannhg/elm-spa/releases)

---

<div class="post-metadata">

**Author:** ![miniBill](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/minibill/32/800_2.png) [@miniBill](https://discourse.elm-lang.org/u/miniBill)\
**Post date:** [April 27, 2021, 5:21pm UTC](https://discourse.elm-lang.org/t/announcing-elm-spa-version-6-0-0/7299/4 "2021-04-27T17:21:11Z")

</div>

This is amazing and I’ll use it for my next project!

Small feedback: in the spirit of being friendly to newcomers, maybe write somewhere that the protected page are still visible in the javascript, to avoid people being mistaken into thinking they aren’t

---

<div class="post-metadata">

**Author:** ![cbrake](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/cbrake/32/438_2.png) [@cbrake](https://discourse.elm-lang.org/u/cbrake)\
**Post date:** [April 27, 2021, 7:19pm UTC](https://discourse.elm-lang.org/t/announcing-elm-spa-version-6-0-0/7299/5 "2021-04-27T19:19:41Z")

</div>

Looks great!

I like the defaults/ and “eject” mechanism. Amazing how this keeps getting simpler to use.

Also like we can now send messages again to the shared module.

I do have one question – where is Effect defined?

```elm
update : Msg -> Model -> ( Model, Effect Msg )
update msg model =
    case msg of
        ClickedSignOut ->
            ( model
            , Effect.fromShared Shared.SignOut
            )

```

---

<div class="post-metadata">

**Author:** ![RyanNHG](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/ryannhg/32/5162_2.png) [@RyanNHG](https://discourse.elm-lang.org/u/RyanNHG)\
**Post date:** [April 27, 2021, 10:45pm UTC](https://discourse.elm-lang.org/t/announcing-elm-spa-version-6-0-0/7299/6 "2021-04-27T22:45:32Z")

</div>

@cbrake

Within the `.elm-spa/defaults` folder.

If you need to customize it, you can drag it to the `src` folder 📂

---

<div class="post-metadata">

**Author:** ![zinggi](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/zinggi/32/62_2.png) [@zinggi](https://discourse.elm-lang.org/u/zinggi)\
**Post date:** [April 28, 2021, 8:32pm UTC](https://discourse.elm-lang.org/t/announcing-elm-spa-version-6-0-0/7299/7 "2021-04-28T20:32:18Z")

</div>

This is awesome, congrats on this release!

Reading through the guide, I’m really digging the simplicity of the selective ejecting technique!

So far I’ve seen other tools with an eject functionality, but those were always a binary choice.  
What was your inspiration for this feature? Is this technique used in other popular tools I don’t know about?

I have a question about the [Page.protected](https://www.elm-spa.dev/guide/03-pages#pageprotected) mechanism. Does this have to be a “user”? Or could I also “protect” pages to require the presence of some other state? E.g. my application might not make sense before configuring a user defined API server URL, so all pages that require this state should be “protected”.  
Would this protected pages feature make sense for this use case too?

---

<div class="post-metadata">

**Author:** ![RyanNHG](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/ryannhg/32/5162_2.png) [@RyanNHG](https://discourse.elm-lang.org/u/RyanNHG)\
**Post date:** [April 28, 2021, 8:52pm UTC](https://discourse.elm-lang.org/t/announcing-elm-spa-version-6-0-0/7299/8 "2021-04-28T20:52:30Z")

</div>

@zinggi your intuition is right! You can provide _any_ type of value to those protected pages, it doesn’t have to be a user!

You’ll still get the guarantee that protected pages will definitely have access to whichever value you’d like them to have.

You can even conditionally redirect to different routes, in the case where you do have signed a user but they should be redirected to a permission denied page.

---

<div class="post-metadata">

**Author:** ![zinggi](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/zinggi/32/62_2.png) [@zinggi](https://discourse.elm-lang.org/u/zinggi)\
**Post date:** [April 28, 2021, 9:10pm UTC](https://discourse.elm-lang.org/t/announcing-elm-spa-version-6-0-0/7299/9 "2021-04-28T21:10:42Z")

</div>

Great, that’s definitely what I need then.  
Before this announcement I was toying with the idea of creating my own custom runtime (a la [Blog: Design your own Runtime](https://discourse.elm-lang.org/t/blog-design-your-own-runtime/6934)) to make those guarantees for a new project. I was also gonna use the effects pattern and would have made some other similar choices.

But after your announcement, I don’t have to, elm-spa seems to cover all my needs already! And much simpler than anything I could have come up with.

Again, congratulations on achieving such simplicity!

---

<div class="post-metadata">

**Author:** ![ymtszw](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/ymtszw/32/2360_2.png) [@ymtszw](https://discourse.elm-lang.org/u/ymtszw)\
**Post date:** [April 29, 2021, 2:35pm UTC](https://discourse.elm-lang.org/t/announcing-elm-spa-version-6-0-0/7299/10 "2021-04-29T14:35:28Z")

</div>

Congratz on release! Some quick feedbacks:

- As people saying, selective eject is really a neat idea 👍
- `Pages.advanced` =\> `Pages.protected.advanced` upgrade path is concise and friction-less ❤
- A bit of confusion on upgrading existing lower-complexity pages (like `static`) to higher ones (`advanced`). Eventually I figured out to perform `elm-spa add /xxx advanced` but the progress on existing page is overwritten. I’m missing somthing, or the doc might need mentioning on that.
- Code-generation by `elm-spa` server/watcher and on-the-fly diagnostics by ElmLS is kinda conflicting. Since recent ElmLS on-the-fly diag runs quite fast by its own (without speaking to `elm make`), it reports faster than `elm-spa`-managed file generations. Resulting in frequent error emissions (like `Gen.Pages.XXX` modules not found.) Though this might better be redirected to @razze @jfmengels (perhaps configurable delay on on-the-fly diags?)

Overall it looks very promising! Somthing that I would like to hear is:

- API stability: do you think current `elm-spa` API is maturing enough, or still foreseeing some non-trivial evolution?
- What is the recommended approach to adopt `elm-spa` to existing non-`elm-spa` Elm apps? That could be quite valuable hook to this tool! (Though such a thing is THE part where the community including myself have a great chance to bring ideas in 😜

---

<div class="post-metadata">

**Author:** ![ymtszw](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/ymtszw/32/2360_2.png) [@ymtszw](https://discourse.elm-lang.org/u/ymtszw)\
**Post date:** [April 29, 2021, 2:50pm UTC](https://discourse.elm-lang.org/t/announcing-elm-spa-version-6-0-0/7299/11 "2021-04-29T14:50:57Z")

</div>

Forgot to add: assertable (`elm-program-test`-able) layer of `Effect` is definitely a wise choise to add!  
It certainly is a non-trivial step from elm-guide for beginners, but helps us in a long run.

---

<div class="post-metadata">

**Author:** ![gorgoroth](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/gorgoroth/32/3355_2.png) [@gorgoroth](https://discourse.elm-lang.org/u/gorgoroth)\
**Post date:** [April 29, 2021, 4:48pm UTC](https://discourse.elm-lang.org/t/announcing-elm-spa-version-6-0-0/7299/12 "2021-04-29T16:48:29Z")

</div>

This is very a wonderful project.  
I have an elm-ui SPA of mine which seems to fit perfectly to be rewritten with elm-spa.

---

<div class="post-metadata">

**Author:** ![Nduati\_Kuria](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/nduati_kuria/32/3733_2.png) [@Nduati\_Kuria](https://discourse.elm-lang.org/u/Nduati_Kuria)\
**Post date:** [April 30, 2021, 1:41pm UTC](https://discourse.elm-lang.org/t/announcing-elm-spa-version-6-0-0/7299/13 "2021-04-30T13:41:34Z")

</div>

Hi Ryan, I am enjoying the library but have been unable to understand the perhaps of the Redirecting\_ Msg or the View.none method. How are we to use these?

---

<div class="post-metadata">

**Author:** ![tlentz](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/tlentz/32/2499_2.png) [@tlentz](https://discourse.elm-lang.org/u/tlentz)\
**Post date:** [May 5, 2021, 3:34pm UTC](https://discourse.elm-lang.org/t/announcing-elm-spa-version-6-0-0/7299/14 "2021-05-05T15:34:49Z")

</div>

Hi Ryan, this is awesome. We are using it to build a project and upgraded to v6.

I was wondering what you consider best practice for updating the shared model from a page.

Currently, we have a `SetSharedModel (Model -> Model)` shared msg that we fire using `Effect.fromShared`

```elm
( model, Shared.SetSharedModel (\sm -> { sm | myField = newValue } |> Effect.fromShared )

```

Is this how you would do it?

---

<div class="post-metadata">

**Author:** ![RyanNHG](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/ryannhg/32/5162_2.png) [@RyanNHG](https://discourse.elm-lang.org/u/RyanNHG)\
**Post date:** [May 5, 2021, 11:34pm UTC](https://discourse.elm-lang.org/t/announcing-elm-spa-version-6-0-0/7299/15 "2021-05-05T23:34:03Z")

</div>

@Nduati_Kuria and @tlentz thank you both for the kind words!

You should join the official `#elm-spa-users` slack channel and ask the wonderful folks there questions like these. I randomly check Discourse, so you’ll receive more timely responses to questions like the ones in this thread.

But since I’m here anyway, I might as well answer these two questions 😃 :

@Nduati_Kuria  
If you mean redirecting users that aren’t signed in, check out the [user authentication example](https://www.elm-spa.dev/examples/04-authentication). If you mean redirecting in general you can learn more about Programmatic Navigation in the [request guide](https://www.elm-spa.dev/guide/04-requests#programmatic-navigation).

A default `View.elm` implementation is generated for you in the `.elm-spa/defaults` folder. You can learn more about customizing that file in the [view guide](https://www.elm-spa.dev/guide/06-views).

@tlentz  
It’s ultimately up to you on how to update the `Shared.Model` in your app, but I would recommend creating a `Shared.Msg` for each shared action you’d like to perform, and pass those messages to `Effect.fromShared`.

This means `Shared.update` can handle all your logic in one place.

The [local storage example](https://www.elm-spa.dev/examples/03-storage) is actually an interesting way to share state between pages without needing `Page.advanced` at all. You can use `Cmd msg` for all the things! This strategy also makes your data is available on refresh, so it doesn’t disappear on you when you close the tab. ( Personally, that’s my favorite way to handle shared state, but I added in `Effect.fromShared` because it’s a lot more intuitive and easy to work with. )

### Thanks everyone for the good vibes!

I’m so glad to see the project is getting folks excited to build cool stuff.

If you make something cool with _elm-spa_, please share it with the community! I personally **love** seeing stuff like that, and it sure beats discovering another thread about typeclasses.

---

<div class="post-metadata">

**Author:** ![roSievers](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/rosievers/32/2465_2.png) [@roSievers](https://discourse.elm-lang.org/u/roSievers)\
**Post date:** [May 10, 2021, 7:47pm UTC](https://discourse.elm-lang.org/t/announcing-elm-spa-version-6-0-0/7299/16 "2021-05-10T19:47:06Z")

</div>

I also just migrated my own website from 5 to 6. Took me a few hours spread across three evenings.

Initially I was struggling a bit with setting up the correct “framing”, figuring out where to put the shared stuff and the shared view. The thing with “there are default generated files and you can move them over if you modify them” didn’t click with me for a while. I also wasn’t sure what old code to remove and which old code to keep. I should definitely set up elm-review next to see which unused code can still be deleted.

Was really happy once I got the website compiling again, even though I had lost all the shared ui and the load/store methods. But getting those back afterwards wasn’t so hard 😃

Thanks for your work providing this framework library!

---

<div class="post-metadata">

**Author:** ![dfeyer](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/dfeyer/32/3985_2.png) [@dfeyer](https://discourse.elm-lang.org/u/dfeyer)\
**Post date:** [May 12, 2021, 9:13am UTC](https://discourse.elm-lang.org/t/announcing-elm-spa-version-6-0-0/7299/17 "2021-05-12T09:13:27Z")

</div>

@RyanNHG Thanks a lots for this library, i upgrade my current project from 5 to 6 last night, so nice, once you convert your first Page 😉 I have to migrate the `save` function to get some feature back, but overall the experience has been quiet good. It’s nice to see Elm SPA design improvements. Thanks for your effort, I think i learn a lots be reading your guides and code.

---

<div class="post-metadata">

**Author:** ![system](https://canada1.discourse-cdn.com/flex035/uploads/elm_lang/original/1X/50a05e53677a2c3b47776d7abd0f113eb50193a1.png) [@system](https://discourse.elm-lang.org/u/system)\
**Post date:** [May 22, 2021, 9:13am UTC](https://discourse.elm-lang.org/t/announcing-elm-spa-version-6-0-0/7299/18 "2021-05-22T09:13:49Z")

</div>

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.
