1
0
Fork
You've already forked conjured.ink
0
a list of nice things
  • Elixir 75.3%
  • HTML 9.8%
  • CSS 8.4%
  • TypeScript 3.5%
  • Dockerfile 1.7%
  • Other 1.1%
2025年08月01日 13:51:35 -07:00
.github/workflows sketch out signup page 2025年08月01日 04:01:05 +02:00
assets update colors 2025年08月01日 10:37:49 -07:00
config swoosh needs an api client 2025年08月01日 13:38:26 -07:00
lib set email sender info 2025年08月01日 13:51:35 -07:00
priv send confirmation emails + unsub 2025年08月01日 13:24:50 -07:00
rel sketch out signup page 2025年08月01日 04:01:05 +02:00
test Establish login link. 2025年08月01日 04:03:07 +02:00
.dockerignore sketch out signup page 2025年08月01日 04:01:05 +02:00
.editorconfig initial commit 2025年07月15日 02:29:40 -07:00
.formatter.exs initial commit 2025年07月15日 02:29:40 -07:00
.gitignore sketch out signup page 2025年08月01日 04:01:05 +02:00
.tool-versions initial commit 2025年07月15日 02:29:40 -07:00
docker-compose.yaml initial commit 2025年07月15日 02:29:40 -07:00
Dockerfile sketch out signup page 2025年08月01日 04:01:05 +02:00
fly.toml put the memory size in the fly.toml 2025年08月01日 09:05:02 -07:00
LICENSE.md add license 2025年07月26日 23:27:20 -07:00
mix.exs sketch out signup page 2025年08月01日 04:01:05 +02:00
mix.lock initial commit 2025年07月15日 02:29:40 -07:00
README.md Fix README links to .tool-versions 2025年07月31日 22:47:44 +01:00

conjured

Table of Contents

Welcome

Indie creatives are at the mercy of the platforms which host their media. At any point, those platforms (or the payment processors which have leverage over them) could decide that they will no longer host certain media, that they'll shadowban it or blacklist it outright. Many platforms have already decided to stop hosting NSFW and queer media.

Conjured Ink is one solution to that. It is software which indexes creative's self-hosted websites (which are referred to as droplets). The artists can then figure out which payment processor is right for them based on their use case and sell their work through that. Or distribute it for free, if no payment processor is required. It is resistant to attacks from payment processors because it's just an index, not a distributor. It doesn't handle payments at all, just links to independent creator's websites, where they can work with services like PayPal, Stripe, etc. (or CCBill or ZenPayments, etc. depending on their media's individual risk case) on their own to sell their products. An attack campaign would have to target each individual creator, not the platform itself.

In practice, this means that there wouldn't be a need for anything like major site-wide blacklists of certain types of media, since Conjured Ink the index is not beholden to any payment processor. The individual creatives pages would be vulnerable to attacks, but it is much higher effort to go after each and every single one, rather than making a larger platform like Itch or Steam do that work for them. Additionally, it's possible for these individual sites to change their payment processor if their current one chooses to pressure them. That's not possible with media that isn't self-hosted, like media distributed through Itch or Steam.

Conjured Ink is just the index; for software to run these self-hosted websites, check out Ichor!

We also maintain a set of resources which might be helpful to someone looking to distribute their media on the wiki, including potentially NSFW friendly payment processors and NSFW friendly web hosting.

FAQ

  1. Is this cryptocurrency, web3, etc. related?

No. Conjured Ink, as an index, does not use anything like cryptocurrency. Individual droplets could, theoretically, use crypto as a payment option if they so desired, but the index has nothing to do with that. Any index, including the official conjured.ink index, could also choose not to index droplets which use web3/crypto.

To stress: Conjured Ink has nothing to do with any cryptocurrency.

  1. Does Conjured Ink fix the root, political issue of payment processor's monopoly?

No. It's not possible to create a tech solution to political issues like these. This is a workaround, a more robust way to sell / distribute your art.

  1. Will Conjured Ink index x media?

The index at the conjured.ink domain might not! If this is a problem for you, the software is available for you to host your own index.

  1. What's stopping conjured.ink from just being taken down?

We don't host any media or process any payments! We're just an index, we just provide links to the places other people distribute their media.

  1. I have no technical skills, can I still host a droplet?

Possibly! Check out Ichor!

We are doing everything we can to make this self-hosting be easy and painless for non-technical folks. Ideally, it will involve guiding you through making a couple of accounts with providers, entering the credentials into a form, and have everything else be automated for you.

  1. My media makes x amount of money, is Conjured Ink right for me?

Ultimately that's up to you to decide.

For free media: The only price you'd pay is the cost of hosting your site and getting a domain, either which could be free. On the low end, you could pay as little as 3ドル per month. You wouldn't face any charges from payment processors.

For low income (but not free) media: check out our list of potentially NSFW friendly payment processors. It's ultimately up to you to decide your risk-case and what would work for you, but Conjured Ink might be useful.

For moderate-high income media: Conjured Ink's probably pretty useful! Once again, check out our list of potentially NSFW friendly payment processors.

Features

  • User accounts, with authentication, login/signup, and email verification
  • User settings page scaffold
  • Primarily server-side rendered, with web components set up for if/when needed
  • Web components are ALSO SSR'd as needed
  • No Tailwind/React/etc. Just plain ol' HTML/CSS, a sprinkling of JS, and good vibes.
  • TypeScript support
  • Full setup for bundling and minifying JS and CSS from sources
  • Ready-to-use i18n and locale detection/configuration
  • Transactional email sending (needs a service for live site)
  • Rate limiting
  • Websockets available if needed (not connected by default)
  • Autoformatting for both JSTS and Elixir code
  • CSS-based light/dark/etc theming support with built-in picker
  • Scaffolded CSP
  • Ready-to-go DNS-based clustering for horizontal scaling (you don't need it)
  • Root template with a bunch of nice things:
    • Mobile size-related meta tags
    • Anti-AI no-scan stuff (on top of included robots.txt). For all the good it'll do :/
    • OpenGraph/"Twitter" card properties, configurable per-page.

Setting up

Prerequisites

Tip

See Using ASDF for Runtimes for a convenient way to handle the first two items below.

  • Elixir and Erlang (Typically auto-installs with Elixir)
  • NodeJS
  • Postgresql v13 or later ATM the tests require a postgres/postgres user/password to run. Check this doc for info on how to reset your postgres password.
    • A docker-compose file is provided that will run postgres configured appropriately
  • inotify-tools (Linux only) - Install through your preferred package manager

Note

You can check .tool-versions in this repository to see what this project is typically developed against.

Important

If postgresql installed via homebrew, make sure to run /usr/local/opt/postgres/bin/createuser -s postgres.

Using ASDF for runtimes

You can use ASDF to install Elixir, Erlang, and NodejS at the correct versions (ensure the necessary build deps are installed first):

asdf plugin add nodejs
asdf plugin add erlang
asdf plugin add elixir
KERL_BUILD_DOCS=yes asdf install # will install erlang (w/ docs), elixir, and nodejs

Additional Tooling

If you're using VS Code, you may find these extensions useful:

Up and Running

Just a couple more commands and we're all set:

  • mix local.hex to install hex package manager
  • mix archive.install hex phx_new
  • If using docker postgres: docker compose up -d
  • mix setup to install deps, create the database, install JS deps, and build JS assets
  • mix phx.server to run the server

Now you can visit localhost:4000 from your browser.

Architecture

Stack

Backend

Frontend

  • Plain old HTML + CSS (only preprocessing for CSS is bundling/minification)
  • Lit for dynamic components
  • TypeScript

JS Considerations and SSR

We use TypeScript for all client-side code, and Lit for all client-side components. Components should be small and focused, preferring to use server-side Phoenix Components whenever possible.

When JavaScript SSR is enabled, we do some additional steps.

We generate as much html/css as possible server-side, and try to keep our JS payloads as small as possible. Server-side rendering, or SSR, is done in three layers:

  1. Phoenix controllers render a dynamic page with as much of the content in regular light DOM as possible. This content can be styled with our global CSS styles, and does not require JS to render/function.
    • This uses Phoenix HEEx templates and Components.
    • Within these templates, we can insert Lit components for things that will absolutely need dynamic, client-side/JS behavior or will otherwise have to do something special to function while offline.
  2. Once Phoenix renders these templates, they're passed through the Plug system, which eventually invokes a Lit server-side renderer.
    • This renderer takes the template, loads all existing components, and pre-renders Lit components as far as server-side work will allow.
    • In components, this behavior can be controlled with isServer.
  3. Finally, all this server-side-rendered content is sent to the client, and Lit components will be "hydrated" after all the other content and JS is loaded.

As a general rule, we operate on "the less JavaScript, the better". Dependencies should be few and far between, preferring to use built-in browser features whenever possible. If a dependency is needed, it should be small and focused, and not introduce a lot of overhead. Obviously, some things in offline apps are just going to bring in some bulk and that's ok, but whenever we have a choice between two things, code size should be a significant consideration in their evaluation.

To minimize JavasScript, we should err on the side of having components be Phoenix-based, and only use Lit components when absolutely necessary: even if they're server-side rendered, their JavaScript definitions still needs to load/hydrate, and are still shipped as part of our .js bundles.

To see what kind of weight a dependency brings in, you can use BundlePhobia.

Folder Structure

  • assets/ - Frontend code
    • css/ - CSS files
      • components/ - CSS for (usually server-side) components
      • app.css - main css entrypoint
      • theme-*.css - variables for themes
      • variables.css - non-theme-specific variables
        • NOTE: While regular styles don't leak into shadow DOM, --variables do, so we can use this for things we need to have consistent styling for.
    • js/ - JS/TS files
      • components/ - Toplevel lit components
      • app.ts - entry point for the overall site JS
      • lit-ssr.ts - lit server-side renderer tool. Used as a server-side script. Kept here for convenience.
      • Other files are pulled in by one of these.
  • config/ - Configuration files
    • Different configs for dev, prod, and test envs.
    • config.exs - common config
    • runtime.exs - more prod config
  • lib/ - Elixir source code
    • conjured/ - core business logic. No web stuff here. All modules are prefixed with Conjured.
    • conjured_web/ - all web stuff here. Modules are prefixed with ConjuredWeb. Uses Conjured for any business logic.
  • priv/ - miscellaneous things
    • gettext/ - this is where our (server-side) i18n stuff lives
    • repo/ - migrations, seeds, etc
    • static/ - static files. JS and CSS are compiled into here (but .gitignored)