A Remix Auth strategy for working with forms.

Overview

FormStrategy

A Remix Auth strategy to work with any form.

Supported runtimes

Runtime Has Support
Node.js
Cloudflare

How to use

This Strategy gives you back on the verify callback the FormData instance of the request and the context from the action if it was was defined.

This let you use any field from that form with the names you want, so you are not limited to only a username+password or email+password, if you need a third field you can use it.

First, install the strategy and Remix Auth.

$ npm install remix-auth remix-auth-form

Then, create an Authenticator instance.

import { Authenticator } from "remix-auth";
import { sessionStorage } from "~/services/session.server";
import { User, findOrCreateUser } from "~/models/user";

export let authenticator = new Authenticator<User>(sessionStorage);

And you can tell the authenticator to use the FormStrategy.

import { FormStrategy } from "remix-auth-form";

// The rest of the code above here...

authenticator.use(
  new FormStrategy(async ({ form, context }) => {
    // Here you can use `form` to access and input values from the form.
    // and also use `context` to access more things from the server
    let username = form.get("username"); // or email... etc
    let password = form.get("password");

    // You can validate the inputs however you want
    invariant(typeof username === "string", "username must be a string");
    invariant(username.length > 0, "username must not be empty");

    invariant(typeof password === "string", "password must be a string");
    invariant(password.length > 0, "password must not be empty");

    // And if you have a password you should hash it
    let hashedPassword = await hash(password);

    // And finally, you can find, or create, the user
    let user = await findOrCreateUser(username, hashedPassword);

    // And return the user as the Authenticator expects it
    return user;
  })
);

In order to authenticate a user, you can use the following inside of an ActionFunction:

export const action: ActionFunction = async ({ request, context }) => {
  return await authenticator.authenticate("form", request, {
    successRedirect: "/",
    failureRedirect: "/login",
    context, // optional
  });
};
Comments
  • Fix redirecting to success when no user is found

    Fix redirecting to success when no user is found

    Currently, the user is redirected to successRedirectonly when an error occurs. However, an error doesn't seem to occur if the user simply doesn't exist. This PR adjusts the check to ensure that the user is redirected to failureRedirect if there is no user but no error occurs

    opened by JeffersonBledsoe 2
  • Separating AuthorizationError from other errors within the strategy?

    Separating AuthorizationError from other errors within the strategy?

    Hey Sergio!

    Given this action:

    export async function action({ request }: ActionArgs) {
      try {
        const form = await request.formData();
    
        validateEmail(form.get("email"));
        validatePasswordAndConfirmation(form.get("password"), form.get("password"));
    
        await authenticator.authenticate("user-pass", request, {
          throwOnError: true,
          context: { formData: form },
          successRedirect: "/profile",
        });
      } catch (error) {
        if (error instanceof AuthorizationError) {
          return json({ error: errorForToast(error.message) }, { status: 401 });
        }
    
        // Because redirects work by throwing a Response, it needs to be re-thrown.
        // Any other generic errors must also be thrown too.
        //
        // The "instanceof Response" line is added here for clarity, but "throw error"
        // would cover it already.
        if (error instanceof Response) throw error;
        throw error;
      }
    }
    

    If any kind of error is thrown internally, such Prisma throwing that the database is down, (https://github.com/sergiodxa/remix-auth-form/blob/5e3d40874ab7832c2151c7484321eee5d24c6e11/src/index.ts#L36), it's sent to this.failure, and then it gets wrapped in AuthorizationError by remix-auth here: https://github.com/sergiodxa/remix-auth/blob/d4e4f85745b13b0bbbb08bdd12375a91de48fd84/src/strategy.ts#LL125C35-L125C35

    So effectively a prisma Error ends up being an AuthorizationError so it's treated no differently from user errors. image

    How can I determine what's an "AuthenticationError" such as wrong username, or password, which I'm doing by specifically throwing that error from within my Authenticator code [1], so that it's shown to users, versus internal server errors, that must not be displayed and should instead return a 500 or be caught by the CatchBoundary?

    In my remix-auth-form strategy I'm specifically throwing AuthorizationError, but the way error handling is done it seems to cast a wider net:

    export const authUserWithEmailAndPassword = async ({
      inputEmail,
      inputPassword,
    }: loginUserArgs): Promise<User> => {
      const blacklisted = await existsByDomainOrEmail(inputEmail);
      if (blacklisted) {
        throw new AuthorizationError(
          "Sorry, your account has been suspended for breaching our Terms of Service."
        );
      }
    
      const user = await getUserByEmail(inputEmail);
      if (!user || !user.password) {
        throw new AuthorizationError("Incorrect email or password");
      }
    
      const passwordMatches = await bcrypt.compare(inputPassword, user.password);
    
      if (!passwordMatches) {
        await incrementFailedLogins(user);
        throw new AuthorizationError("Incorrect email or password");
      }
    
      await createLoginRecord({ userId: user.id, email: inputEmail });
    
      return user;
    
    opened by bbonamin 1
  • Check and refresh session

    Check and refresh session

    With the current solution an user is authenticated as long as a valid session cookie is provided. What I miss is a checkSession function like in remix-auth-supabase to validate the user against the database while he still has a valid session cookie. When checkSession is called successfully we can also set the session cookie again to keep the user logged in.

    How do you like the idea? I would be open to help with the implementation.

    opened by roydigerhund 1
  • BUG: request.formData is not a function

    BUG: request.formData is not a function

    Description

    I get request.formData is not a function error when I submit my login form

    // auth.server.ts
    import { Authenticator } from "remix-auth"
    import { FormStrategy } from "remix-auth-form"
    
    import type { User } from "@prisma/client"
    
    import { loginSchema } from "~/validation"
    import { sessionStorage } from "~/services/session.server"
    
    export const authenticator = new Authenticator<User>(sessionStorage)
    
    authenticator.use(
    	new FormStrategy(async ({ form }) => {
    		const userInput = Object.fromEntries(form)
    		const { email, password } = await loginSchema.validate(userInput)
    		let user = await login(email, password)
    		return user
    	}),
    	"form"
    )
    
    // routes/login.tsx
    import type { VFC } from "react"
    import type { ActionFunction } from "remix"
    
    import { Form } from "remix"
    import { authenticator } from "~/services/auth.server"
    
    export const action: ActionFunction = async ({ request }) => {
    	await authenticator.authenticate("form", request, {
    		failureRedirect: "/login",
    		successRedirect: "/",
    	})
    	return {}
    }
    
    
    const Login: VFC = () => {
    	return (
    		<Form method="post">
    			<label>
    				email
    				<input type="email" name="email" />
    			</label>
    			<label>
    				password
    				<input type="password" name="password" />
    			</label>
    			<button type="submit">Login</button>
    		</Form>
    	)
    }
    
    export default Login
    

    More Info about packages and installed version

    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "remix": "^1.0.6",
    "remix-auth": "^2.5.0-0",
    "remix-auth-form": "^1.1.1",
    "@remix-run/dev": "^1.0.6",
    "@remix-run/react": "^1.0.6",
    "@remix-run/serve": "^1.0.6",
    
    opened by nimaa77 1
  • Feature: Bundle a hashing function

    Feature: Bundle a hashing function

    Would it be worth providing a small hash function to the authenticate method?

    This adds a bit of opinion about the right way to store passwords, but in this case I think a bit of well educated opinion would go a long way toward encouraging good security practices with a well chosen hash, like PBKDF2 which crypto-js supports (and is Cloudflare workers compliant)

    authenticate({ form, hash }) { }
    
    opened by jacobparis 1
  • Bump decode-uri-component from 0.2.0 to 0.2.2

    Bump decode-uri-component from 0.2.0 to 0.2.2

    Bumps decode-uri-component from 0.2.0 to 0.2.2.

    Release notes

    Sourced from decode-uri-component's releases.

    v0.2.2

    • Prevent overwriting previously decoded tokens 980e0bf

    https://github.com/SamVerschueren/decode-uri-component/compare/v0.2.1...v0.2.2

    v0.2.1

    • Switch to GitHub workflows 76abc93
    • Fix issue where decode throws - fixes #6 746ca5d
    • Update license (#1) 486d7e2
    • Tidelift tasks a650457
    • Meta tweaks 66e1c28

    https://github.com/SamVerschueren/decode-uri-component/compare/v0.2.0...v0.2.1

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • Bump minimatch from 3.0.4 to 3.1.2

    Bump minimatch from 3.0.4 to 3.1.2

    Bumps minimatch from 3.0.4 to 3.1.2.

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • Require at least remix-auth 3.3.0

    Require at least remix-auth 3.3.0

    I ran into an issue where passing formData via context (https://github.com/sergiodxa/remix-auth-form/commit/711b39e247831c1f94c5c0bdd19aa979b419c77e) doesn't work without https://github.com/sergiodxa/remix-auth/commit/50a58e0ec194dd854d900ae65c4b8d5fde47834e. This commit bumps the remix-auth dependency to the version that includes that commit.

    dependencies 
    opened by gdpotter 0
  • Bump cross-fetch from 3.1.4 to 3.1.5

    Bump cross-fetch from 3.1.4 to 3.1.5

    Bumps cross-fetch from 3.1.4 to 3.1.5.

    Release notes

    Sourced from cross-fetch's releases.

    v3.1.5

    What's Changed

    New Contributors

    Full Changelog: https://github.com/lquixada/cross-fetch/compare/v3.1.4...v3.1.5

    Commits
    • c6089df chore(release): 3.1.5
    • a3b3a94 chore: updated node-fetch version to 2.6.7 (#124)
    • efed703 chore: updated node-fetch version to 2.6.5
    • 694ff77 refactor: removed ora from dependencies
    • efc5956 refactor: added .vscode to .gitignore
    • da605d5 refactor: renamed test/fetch/ to test/fetch-api/ and test/module/ to test/mod...
    • 0f0d51d chore: updated minor and patch versions of dev dependencies
    • c6e34ea refactor: removed sinon.js
    • f524a52 fix: yargs was incompatible with node 10
    • 7906fcf chore: updated dev dependencies
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • Bump minimist from 1.2.5 to 1.2.6

    Bump minimist from 1.2.5 to 1.2.6

    Bumps minimist from 1.2.5 to 1.2.6.

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • AppLoadContext type seems to not match how it is designed to work

    AppLoadContext type seems to not match how it is designed to work

    I am trying to work out how to get some arbitrary data into the form strategy as a means of creating an history of sign-in but the type on the context object seems strange.

    export async function action({ context, request }: ActionArgs) {
      return await authenticator.authenticate("form", request, {
        successRedirect: "/",
        failureRedirect: "/login",
        context, // optional
      });
    };
    

    on this one, you are passing the remix context - which is all good.

    but then you also override it with formData on the next one.

    export async function action({ context, request }: ActionArgs) {
      let formData = await request.formData();
      return await authenticator.authenticate("form", request, {
        // use formData here
        successRedirect: formData.get("redirectTo"),
        failureRedirect: "/login",
        context: { formData }, // pass pre-read formData here
      });
    };
    

    but it should still be typed as AppLoadContext, It seems like this type might want to be generic or somehow user customizable? is that a fair assumption?

    (ps happy to submit a pr if worthwhile)

    opened by samjohnduke 0
  • request.formData is undefined

    request.formData is undefined

    remix-auth: 3.2.1 remix-auth-form: 1.1.1

    after configuring everything and hitting the login button I get an error saying request.formData is not a function. I tranced it back to the request.clone() found in authenticator.js:88 return strategyObj.authenticate(request.clone(), this.sessionStorage, {... removing the .clone() and I get no error. could it be that cloning removed the formData ?

    opened by gabimor 0
Releases(v1.3.0)
  • v1.3.0(Nov 25, 2022)

    What's Changed

    Documentation Changes

    • Use ActionArgs instead of ActionFunction by @MichaelDeBoey in https://github.com/sergiodxa/remix-auth-form/pull/16
    • Fix spelling on README by @Matthew-Mallimo in https://github.com/sergiodxa/remix-auth-form/pull/17

    New Features

    • Add original error as cause by @sergiodxa in https://github.com/sergiodxa/remix-auth-form/pull/23

    Other Changes

    • Require at least remix-auth 3.3.0 by @gdpotter in https://github.com/sergiodxa/remix-auth-form/pull/15
    • Bump minimatch from 3.0.4 to 3.1.2 by @dependabot in https://github.com/sergiodxa/remix-auth-form/pull/19

    New Contributors

    • @gdpotter made their first contribution in https://github.com/sergiodxa/remix-auth-form/pull/15
    • @MichaelDeBoey made their first contribution in https://github.com/sergiodxa/remix-auth-form/pull/16
    • @Matthew-Mallimo made their first contribution in https://github.com/sergiodxa/remix-auth-form/pull/17

    Full Changelog: https://github.com/sergiodxa/remix-auth-form/compare/v1.2.0...v1.3.0

    Source code(tar.gz)
    Source code(zip)
  • v1.2.0(Sep 8, 2022)

    What's Changed

    New Features

    • Use context.formData if available over request.formData() by @sergiodxa in https://github.com/sergiodxa/remix-auth-form/pull/14

    Full Changelog: https://github.com/sergiodxa/remix-auth-form/compare/v1.1.2...v1.2.0

    Source code(tar.gz)
    Source code(zip)
  • v1.1.2(Apr 29, 2022)

    What's Changed

    Other Changes

    • Bump minimist from 1.2.5 to 1.2.6 by @dependabot in https://github.com/sergiodxa/remix-auth-form/pull/11
    • Bump cross-fetch from 3.1.4 to 3.1.5 by @dependabot in https://github.com/sergiodxa/remix-auth-form/pull/12

    New Contributors

    • @dependabot made their first contribution in https://github.com/sergiodxa/remix-auth-form/pull/11

    Full Changelog: https://github.com/sergiodxa/remix-auth-form/compare/v1.1.1...v1.1.2

    Source code(tar.gz)
    Source code(zip)
  • v1.1.1(Dec 29, 2021)

    What's Changed

    New Features

    • Fix context type in verify params by @sergiodxa in https://github.com/sergiodxa/remix-auth-form/pull/6

    Full Changelog: https://github.com/sergiodxa/remix-auth-form/compare/v1.1.0...v1.1.1

    Source code(tar.gz)
    Source code(zip)
  • v1.1.0(Dec 29, 2021)

    What's Changed

    Documentation Changes

    • Document how to use FormStrategy by @sergiodxa in https://github.com/sergiodxa/remix-auth-form/pull/2
    • docs: add example action + fix async function by @rcssdy in https://github.com/sergiodxa/remix-auth-form/pull/3
    • Document context usage in the verify callback by @sergiodxa in https://github.com/sergiodxa/remix-auth-form/pull/5

    New Features

    • Add context support by @sergiodxa in https://github.com/sergiodxa/remix-auth-form/pull/4

    New Contributors

    • @sergiodxa made their first contribution in https://github.com/sergiodxa/remix-auth-form/pull/2
    • @rcssdy made their first contribution in https://github.com/sergiodxa/remix-auth-form/pull/3

    Full Changelog: https://github.com/sergiodxa/remix-auth-form/compare/v1.0.0...v1.1.0

    Source code(tar.gz)
    Source code(zip)
  • v1.0.0(Dec 24, 2021)

Owner
Sergio Xalambrí
Web Dev at Daffy.org. Previously: @ableco, @codeableorg, @platzi (YC W15), and @vercel
Sergio Xalambrí
Remix Stack for deploying to Vercel with remix-auth, Planetscale, Radix UI, TailwindCSS, formatting, linting etc. Written in Typescript.

Remix Synthwave Stack Learn more about Remix Stacks. npx create-remix --template ilangorajagopal/synthwave-stack What's in the stack Vercel deploymen

Ilango 56 Dec 25, 2022
Angular 14 JWT Authentication & Authorization with Web API and HttpOnly Cookie - Token Based Auth, Router, Forms, HttpClient, BootstrapBootstrap

Angular 14 JWT Authentication with Web API and HttpOnly Cookie example Build Angular 14 JWT Authentication & Authorization example with Web Api, HttpO

null 20 Dec 26, 2022
Grupprojekt för kurserna 'Javascript med Ramverk' och 'Agil Utveckling'

JavaScript-med-Ramverk-Laboration-3 Grupprojektet för kurserna Javascript med Ramverk och Agil Utveckling. Utvecklingsguide För information om hur utv

Svante Jonsson IT-Högskolan 3 May 18, 2022
Hemsida för personer i Sverige som kan och vill erbjuda boende till människor på flykt

Getting Started with Create React App This project was bootstrapped with Create React App. Available Scripts In the project directory, you can run: np

null 4 May 3, 2022
Kurs-repo för kursen Webbserver och Databaser

Webbserver och databaser This repository is meant for CME students to access exercises and codealongs that happen throughout the course. I hope you wi

null 14 Jan 3, 2023
Auth-Form-Design - Beautiful Auth Form Designed using React 🥰.

?? Auth Form Design ?? Features 1. Check Your Password Strength 2. Can Use Suggested Password 3. Enjoy Responsive Design Getting Started with Create R

Samarpan Dasgupta 2 Dec 24, 2022
Firebase adepter auth process with custom token example in Next Auth

Firebase adepter auth process with custom token example in Next Auth Example of a firebase adapter that works with firebase authentication. A firebase

Low Front 10 Oct 14, 2022
Magically create forms + actions in Remix!

Welcome to Remix Forms! This repository contains the Remix Forms source code. We're just getting started and the APIs are unstable, so we appreciate y

Seasoned 321 Dec 29, 2022
A collection of social media strategies for remix-auth

Remix Auth Socials A collection of Remix Auth strategies for Oauth2 Social logins. ?? If you are interested in creating one of the planned strategies,

Tom Rowe 80 Jan 5, 2023
Remix Auth plugin for Twitter OAuth 1.0a

Remix Auth Twitter Remix Auth plugin for Twitter OAuth 1.0a. Supported runtimes Runtime Has Support Node.js ✅ Cloudflare ✅ Demo Try out live demo (sou

na2hiro 13 Dec 31, 2022
The Remix version of the fakebooks app demonstrated on https://remix.run. Check out the CRA version: https://github.com/kentcdodds/fakebooks-cra

Remix Fakebooks App This is a (very) simple implementation of the fakebooks mock app demonstrated on remix.run. There is no database, but there is an

Kent C. Dodds 61 Dec 22, 2022
Remix enables you to build fantastic user experiences for the web and feel happy with the code that got you there. In this workshop, we'll look at some more advanced use cases when building Remix applications.

?? Advanced Remix Workshop Remix enables you to build fantastic user experiences for the web and feel happy with the code that got you there. In this

Frontend Masters 167 Dec 9, 2022
Remix enables you to build fantastic user experiences for the web and feel happy with the code that got you there. Get a jumpstart on Remix with this workshop.

?? Remix Fundamentals Build Better websites with Remix Remix enables you to build fantastic user experiences for the web and feel happy with the code

Frontend Masters 204 Dec 25, 2022
simple-remix-blog is a blog template built using Remix and TailwindCSS. Create your own blog in just a few minutes!

simple-remix-blog is a blog template built using remix.run and TailwindCSS. It supports markdown and MDX for the blog posts. You can clone it and star

José Miguel Álvarez Vañó 8 Dec 8, 2022
Use pulsar to make custom trading strategy that uses Flashloans at low cost. No contract deployment required.

PULSAR Pulsar is a contract that will let you execute custom call on the blockchain and let you make use of the Flasloans in your trading sequences. Y

idecentralize.finance 9 Jun 6, 2022
A template application for setting up a mobile app video game with IONIC, PHASER, ANGULAR and a Monorepo strategy

OpenForge Ionic Monorepo Example This is a template project for all you aspiring video game developers out there! Want to use your web application ski

OpenForge 67 Dec 22, 2022
True P2P concept for your p2p powered website/app/client. MSC/MEP (Multiple Strategy Concept/Multiple Entry Points)

TRUE P2P CONCEPT - Lets redecentralize the web This repo is just conceptual. Active development of the endproduct (TRUE P2P) happens here https://gith

Bo 6 Mar 29, 2022
FCIV.NET is a open source strategy game loosely based on Freeciv

FCIV.NET FCIV.NET is an open-source turn-based strategy game. It can be played in any HTML5 capable web-browser and features in-depth game-play and a

FCIV.NET 13 Nov 22, 2022
Debut plugin that provides additional candles of specified tickers to strategy.

debut-plugin-candles A plugin for Debut platform that provides additional candles of specified tickers to strategy. Install @debut/community-core shou

Denis Mainhardt 2 Dec 15, 2022