Lucidboard: A Kanban Tool with Phoenix LiveView

Hello, Elixir Forum!

I just wanted to take a moment to share a personal (MIT-licensed) project I’ve been working on recently. It’s called Lucidboard, and it’s more or less a Trello clone. It’s a real-time, collaborative tool where folks can all work on the same board at the same time. Cards can be created, arranged in columns, and voted on. Just this basic functionality is very useful for lean coffee and retrospective meetings as well as simple brainstorming or planning.

I work at a big company, and I actually built the original version of this application about 5 years ago, using Node.js and Angular 1.x. After all this time, despite bugs, performance issues, and a complete lack of ownership or maintenance, quite a number of teams are still using it! In my quest to share my love for the astonishingly good Elixir stack, I set about rebuilding the tool. We’ve just deployed it for team members to use a couple weeks ago, and the feedback is very positive so far; folks are jumping in and using it for their daily work already!

I want this to be a community effort, so I’ve accepted pull requests from a number of my teammates. If anyone out there might be interested to contribute anything, reach out & jump in! We welcome pull requests!

The idea is to start simple, and I think we’ve met this target by now. From here, we would like to continue adding features, many of which will be options, per board. For instance, you might like to see WHO created a card or have someone’s name as having a related action item. Perhaps comment threads on cards is important to you or a task status-type field. These things could be toggled as needed, and board templates let you create a new board with a pre-defined set of these settings.

As for roles, we currently have board “ownership” which allows someone to manage the board settings, and this can be delegated to other users. A nearer-term feature I think will be “private” boards where owners can grant others “observer” or “contributor” roles on the board to allow them to view or interact.

I think it goes without saying how incredible LiveView and of course the Elixir language has been in developing this, particularly but not nearly limited to the real-time aspects. Not needing to deal with client-side state is a massive relief, compared to the original version which where everything had to be implemented twice – once on the server and once in the browser. And I feel like the code is organized and easy to work with: a complete reversal to how I feel about the original project.

At any rate, feel free to set up an instance of this for yourself and play around. A local, docker-based dev environment can be spun up very easily. We’d love to hear what you think!

And thanks to @AstonJ for the invite to make this post. :slight_smile:


Looks great Adam, thanks for sharing :023:

1 Like

looks awesome! :clap: :clap:

tried to get it to run in dev… can you post a pseudo dev.secret.exs for quick setting up? (lazywebbing a bit here :man_facepalming:) or did I miss a doc?


try bin/dev to start elixir and postgres docker containers, or bin/db if you’d rather use elixir on your host. Either way, it should create the dev.secret.exs file.

Let me know if you still have trouble!


ahh there it is… told u I was lazywebbing (no docker here…)

creating dev.secret.exs with:

use Mix.Config

config :lucidboard, Lucidboard.Repo,
  adapter: Ecto.Adapters.Postgres,
  username: System.get_env("PG_USER") || "yourpguser",
  password: System.get_env("PG_PASS") || "yourpass",
  database: System.get_env("PG_DB") || "lucidboard_dev",
  hostname: System.get_env("PG_HOST") || "localhost",
  pool_size: 10

and then

mix deps.get
cd assets; npm install; cd ..
mix ecto.setup
iex -S mix phx.server

got me going without docker - looks great, and impressive with liveview!

one bug:
create new board
create new card
notice dnd doesn’t work
reload - and it works…

debug and notice:
<meta name="board_id" content="#{board_id}">

isn’t being set when using the live_redirect(socket, to: Routes.live_path(socket, BoardLive, id)) in create_board_live.ex

notice it is being set correctly when using href="<%= Routes.live_path(LucidboardWeb.Endpoint, BoardLive, %>" in the dashboard template and dnd works then…

no clue - could be a liveview bug


Fantastic. Thank you so much for mentioning that, @outlog!

Setting up the create board screen as a LiveView was one of the last things I did, and I didn’t notice that regression.

It’s fixed in the latest master as I’m now sending you to the board you just created with redirect instead of live_redirect, so it loads the whole page. I was actually surprised that live_redirect actually worked in the first place as the board is an entirely separate LiveView. I figure this usage with live_redirect may or may not be something LV would ultimately support.

1 Like