🌊 Elixir RSS/ATOM feed builder with a focus on standards compliance, security and extensibility

Latest version: 0.5.1 registry icon
Maintenance score
Safety score
Popularity score
Check your open source dependency risks. Get immediate insight about security, stability and licensing risks.
Version Suggest Low Medium High
0.5.1 0 0 0 0
0.4.1 0 0 0 0
0.4.0 0 0 0 0
0.3.0 0 0 0 0
0.2.0 0 0 0 0

Latest release:

0.5.1 - this version is safe to use because it has no known security vulnerabilities at this time. Find out if your coding project uses this component and get notified of any reported security vulnerabilities with Meterian-X Open Source Security Platform


Maintain your licence declarations and avoid unwanted licences to protect your IP the way you intended.

MIT   -   MIT License

Not a wildcard

Not proprietary

OSI Compliant


Coverage Status Build Status

Atomex is an ATOM 1.0 feed builder with a focus on RFC4287 compliance, security and extensibility. It is safe to use it with user content: everything is escaped by default. Built on top of xml_builder.

API reference is available here:


  • [x] Feed required params (id, title, updated)
  • [x] Feed recommended params (author, link)
  • [x] Feed optional params
    • [x] category
    • [x] contributor
    • [x] generator
    • [x] icon
    • [x] logo
    • [x] rights
    • [x] subtitle
  • [x] Entry required params (id, title, updated)
  • [x] Entry recommended params (author, content, link, summary)
  • [ ] Entry optional params
    • [x] category
    • [x] contributor
    • [x] published
    • [x] rights
    • [ ] source
  • [ ] Validator


def deps do
    {:atomex, "0.3.0"}

Basic usage

Required field are always passed in new functions. There are however recommended fields that you should not ignore. See Validating your feed below.

alias Atomex.{Feed, Entry}

def build_feed(comments) do"", DateTime.utc_now, "My incredible feed")
  |>"John Doe", email: "")
  |>"", rel: "self")
  |> Feed.entries(, &get_entry/1))
  |> Atomex.generate_document()

defp get_entry(_comment = %{id, text, inserted_at, user}) do"{id}", inserted_at, "New comment by #{}")
  |>, uri: "{}")
  |> Entry.content("<h1>Content here will be properly escaped! Text: #{text}</h1>", type: "html")

To avoid escaping, you can pass a tuple as value like this (be careful though, a user may break it with malicious content):

Entry.content(entry, {:cdata, "<h1>Amazing</h1>"}, type: "html")
# Render as => <content type="html"><![CDATA[<h1>Amazing</h1>]]></content>

Extending the default API

  • You can specify custom schemas, %{"xmlns:georss" => ""})
# <?xml version="1.0" encoding="UTF-8"?>
# <rss version="2.0" xmlns="" xmlns:georss="">
  • And custom fields
|> Feed.add_field(:custom_field, %{attribute: 42}, "Foobar")
|> Atomex.generate_document()
# ...
# <custom_field attribute="42">Foobar</custom_field>

For more complicated use cases, content can also be given a xml element directly. Use XmlBuilder to achieve that.

Validating your feed

Use this tool from W3C