How to Start Contributing to Open Source
Acme Design is a full service design agency.
Why contribute to open source?
How to find a project to contribute to?
How to submit your first contribution?
Why contribute to open source?
Why contribute to open source?
Improve software you rely on
Why contribute to open source?
Improve software you rely on
Improve your skills
Why contribute to open source?
Improve software you rely on
Improve your skills
Learn new things and teach others
Why contribute to open source?
Improve software you rely on
Improve your skills
Learn new things and teach others
Improve communication skills
Why contribute to open source?
Improve software you rely on
Improve your skills
Learn new things and teach others
Improve communication skills
It's empowering
Blitz framework was created by Brandon and the community
We decided to fork Next.js, weekly downloads started to decline
We released an alpha version of the Blitz 2.0
Blitz reaching 11k GitHub stars. People loved it
We posted an RFC about Blitz pivot, it was very well received
Feb, 2020
2020 – 2021
Mar, 2021
Dec, 2021
Apr, 2021
The Fullstack JavaScript Framework
Next.js
Recipes
Zero-API Layer
React-query
Code scaffolding
AuthN & AuthZ
Prisma
Zod utilites
Misc utilities
The Fullstack JavaScript Toolkit
npm i -g blitz@alpha
blitz new my-new-blitz-project
// app/blitz-server.ts
import { setupBlitzServer } from "@blitzjs/next"
import { AuthServerPlugin, PrismaStorage } from "@blitzjs/auth"
import { db } from "db"
import { simpleRolesIsAuthorized } from "@blitzjs/auth"
const { gSSP, gSP, api } = setupBlitzServer({
plugins: [
AuthServerPlugin({
cookiePrefix: "blitz-app",
storage: PrismaStorage(db),
isAuthorized: simpleRolesIsAuthorized,
}),
],
})
export { gSSP, gSP, api }
// app/blitz-client.ts
import { AuthClientPlugin } from "@blitzjs/auth"
import { setupBlitzClient } from "@blitzjs/next"
import { BlitzRpcPlugin } from "@blitzjs/rpc"
export const { withBlitz } = setupBlitzClient({
plugins: [
AuthClientPlugin({
cookiePrefix: "blitz-app",
}),
BlitzRpcPlugin({
reactQueryOptions: {
queries: {
staleTime: 7000,
},
},
}),
],
})
// app/products/queries/getProduct.ts
import db from "db"
import * as z from "zod"
const GetProject = z.object({
id: z.number(),
})
export default async function getProject(
input: z.infer<typeof GetProject>,
) {
const data = GetProject.parse(input)
const project = await db.project.findOne({ where: { id: data.id } })
return project
}
import { Suspense } from "react"
import { useQuery, useRouter, useParam } from "blitz"
import getProject from "app/projects/queries/getProject"
function Project() {
const router = useRouter()
const projectId = useParam("projectId", "number")
const [project] = useQuery(getProject, { where: { id: projectId } })
return <div>{project.name}</div>
}
function ProjectPage() {
return (
<Suspense fallback={<div>Loading...</div>}>
<Project />
</Suspense>
)
}
export default ProjectPage
// app/products/mutations/createProduct.tsx
import db from "db"
import * as z from "zod"
const CreateProject = z
.object({
name: z.string(),
})
export default async function createProject(
input: z.infer<typeof CreateProject>,
) {
const data = CreateProject.parse(input)
const project = await db.project.create({ data })
return project
}
import {useMutation} from 'blitz'
import updateProject from 'app/projects/mutations/updateProject'
function (props) {
const [updateProjectMutation] = useMutation(updateProject)
return (
<Formik
onSubmit={async values => {
try {
const project = await updateProjectMutation(values)
} catch (error) {
alert('Error saving project')
}
}}>
{/* ... */}
</Formik>
)
}
// app/auth/mutations/signup.ts
import { resolver, SecurePassword } from "blitz"
import db from "db"
import { Signup } from "app/auth/validations"
import { Role } from "types"
export default resolver.pipe(resolver.zod(Signup), async ({ email, password }, ctx) => {
const hashedPassword = await SecurePassword.hash(password.trim())
const user = await db.user.create({
data: { email: email.toLowerCase().trim(), hashedPassword, role: "USER" },
select: { id: true, name: true, email: true, role: true },
})
await ctx.session.$create({ userId: user.id, role: user.role as Role })
return user
})
// app/products/queries/getProduct.tsx
import {Ctx} from "blitz"
import db from "db"
import * as z from "zod"
const GetProject = z.object({
id: z.number(),
})
export default async function getProject(
input: z.infer<typeof GetProject>,
ctx: Ctx
) {
const data = GetProject.parse(input)
ctx.session.$authorize(),
const project = await db.project.findOne({ where: { id: data.id } })
return project
}
import { Routes } from "@blitzjs/next"
const Page: BlitzPage = () => {
return <div>{/* ... */}</div>
}
Page.redirectAuthenticatedTo = "/"
Page.redirectAuthenticatedTo = Routes.Home()
Page.redirectAuthenticatedTo = ({ session }) =>
session.role === "admin" ? "/admin" : Routes.Home()
Page.authenticate = true
Page.authenticate = {redirectTo: '/login'}
Page.authenticate = {redirectTo: Routes.Login()}
Zero-API Data Layer ✅ ✅
Authentication, authorization ✅ ✅
New app templates ✅ ✅
Code scaffolding ✅ ✅
Recipes ✅ ✅
Websockets 🚀
Cron, scheduled job, job queues 🚀
Mailers/Email integration 🚀
File uploads 🚀
Billing integration 🚀
GraphQL data layer 🚀
➡️ https://canary.blitzjs.com/
➡️ https://github.com/blitz-js/blitz