├── .cursorrules
├── .env.example
├── .gitignore
├── .npmignore
├── .nvmrc
├── .prettierrc
├── .vscode
├── extensions.json
├── launch.json
└── settings.json
├── CODE_OF_CONDUCT.md
├── LICENSE
├── README.md
├── astro.config.mjs
├── db
├── config.ts
└── seed.ts
├── netlify.toml
├── package-lock.json
├── package.json
├── public
├── _redirects
├── favicon.svg
├── og-image.png
└── robots.txt
├── scripts
├── check-env.js
├── create-freedom-stack.js
└── setup-turso.js
├── src
├── actions
│ ├── auth.ts
│ ├── index.ts
│ └── posts.ts
├── assets
│ ├── deploy.png
│ ├── full-stack.png
│ └── sections.png
├── components
│ ├── IconBlock.astro
│ ├── RenderMarkdown.astro
│ ├── ShowIfAuthenticated.astro
│ ├── TrixEditor.astro
│ ├── sections
│ │ ├── Container.astro
│ │ ├── FAQ.astro
│ │ ├── Features
│ │ │ ├── Card.astro
│ │ │ └── index.astro
│ │ ├── Footer.astro
│ │ ├── HalfTextHalfImage.astro
│ │ ├── Hero.astro
│ │ ├── Navbar.astro
│ │ └── Quote.astro
│ └── server
│ │ └── GithubButton.astro
├── entrypoint.ts
├── env.d.ts
├── global.css
├── icons
│ └── astro.svg
├── layouts
│ └── Layout.astro
├── lib
│ ├── auth-client.ts
│ ├── auth.ts
│ └── email.ts
├── middleware.ts
└── pages
│ ├── api
│ ├── auth
│ │ └── [...all].ts
│ ├── create-post.ts
│ └── htmx-partials
│ │ ├── github-stars.astro
│ │ ├── rick-roll.astro
│ │ └── uneed-launch.astro
│ ├── dashboard
│ ├── index.astro
│ └── posts
│ │ ├── edit
│ │ └── [slug].astro
│ │ └── new.astro
│ ├── forgot-password.astro
│ ├── index.astro
│ ├── posts
│ ├── [...slug].astro
│ └── index.astro
│ ├── sign-in.astro
│ ├── sign-out.astro
│ ├── sign-up.astro
│ ├── sitemap.xml.ts
│ └── verify-email.astro
└── tsconfig.json
/.cursorrules:
--------------------------------------------------------------------------------
1 | You are an expert in JavaScript, TypeScript, and Astro framework for scalable web development.
2 |
3 | Technology Stack:
4 |
5 | UI Layer:
6 |
7 | - Framework: Astro
8 | - Styling: TailwindCSS, Preline UI, DaisyUI
9 | - Icons: Lucide Icons
10 | - File Pattern: \*.astro
11 | - Rich Text Editor: Trix
12 |
13 | Interactivity Layer:
14 |
15 | - Language: TypeScript
16 | - Frameworks: Alpine.js, HTMX
17 | - Alpine Plugins: Intersect, Persist, Collapse, Mask
18 | - File Pattern: _.ts, _.tsx
19 |
20 | Backend Layer:
21 |
22 | - ORM: Drizzle via Astro DB
23 | - Database: Astro DB (with libSQL/Turso)
24 | - Authentication: Better Auth
25 | - Cache: Netlify
26 | - File Pattern: db/\*.ts
27 |
28 | Development Guidelines:
29 |
30 | - Enforce strict TypeScript settings for type safety
31 | - Use DaisyUI and TailwindCSS with utility-first approach (never use @apply)
32 | - Create modular, reusable Astro components
33 | - Maintain clear separation of concerns
34 | - Implement proper cache control headers
35 | - Sanitize HTML content using DOMPurify
36 | - Use Markdown for content formatting (marked)
37 | - Leverage Astro's partial hydration and multi-framework support
38 | - Prioritize static generation and minimal JavaScript
39 | - Use descriptive variable names and follow Astro's conventions
40 |
41 | Project Structure:
42 |
43 | - src/
44 | - components/
45 | - layouts/
46 | - pages/
47 | - styles/
48 | - public/
49 | - astro.config.mjs
50 |
51 | Component Development:
52 |
53 | - Create .astro files for Astro components
54 | - Use framework-specific components when necessary
55 | - Implement proper component composition
56 | - Use Astro's component props for data passing
57 | - Leverage built-in components like
58 |
59 | Routing and Pages:
60 |
61 | - Utilize file-based routing in src/pages/
62 | - Implement dynamic routes using [...slug].astro
63 | - Use getStaticPaths() for static page generation
64 | - Implement proper 404 handling
65 |
66 | Content Management:
67 |
68 | - Use Markdown (.md) or MDX (.mdx) for content-heavy pages
69 | - Leverage frontmatter in Markdown files
70 | - Implement content collections
71 |
72 | Performance Optimization:
73 |
74 | - Minimize client-side JavaScript
75 | - Use client:\* directives judiciously:
76 | - client:load for immediate needs
77 | - client:idle for non-critical
78 | - client:visible for viewport-based
79 | - Implement proper lazy loading
80 | - Utilize built-in asset optimization
81 |
82 | Code Style Requirements:
83 |
84 | - Indentation: 2 spaces (tabWidth: 2, useTabs: false)
85 | - Enable format on save
86 | - No trailing comma (trailingComma: "none")
87 | - Line length: 120 characters (printWidth: 120)
88 | - Trim trailing whitespace
89 | - Ensure final newline
90 | - Include path/filename as first comment
91 | - Write purpose-focused comments
92 | - Follow DRY principles
93 | - Prioritize modularity and performance
94 | - Use Astro-specific parser for .astro files
95 | - Use prettier-plugin-astro for Astro file formatting
96 |
97 | Commit Message Standards:
98 |
99 | - Use conventional commits with lowercase type and optional scope
100 | - Keep messages concise (max 60 characters)
101 | - Format: type(scope): description
102 | - Include full commit command in suggestions
103 | - Messages should be terminal-ready
104 |
105 | Environment Variables:
106 |
107 | - ASTRO_DB_REMOTE_URL: libSQL connection URL
108 | - ASTRO_DB_APP_TOKEN: libSQL auth token
109 | - BETTER_AUTH_SECRET: Better Auth secret
110 | - BETTER_AUTH_URL: Better Auth URL
111 |
112 | Testing and Accessibility:
113 |
114 | - Implement unit tests for utility functions
115 | - Use end-to-end testing with Cypress
116 | - Ensure proper semantic HTML structure
117 | - Implement ARIA attributes where necessary
118 | - Ensure keyboard navigation support
119 |
120 | Documentation Resources:
121 |
122 | - DaisyUI: https://daisyui.com/
123 | - TailwindCSS: https://tailwindcss.com/
124 | - Preline: https://preline.co/
125 | - Astro DB: https://docs.astro.build/en/guides/astro-db
126 | - HTMX: https://htmx.org/
127 | - Better Auth: https://better-auth.com/
128 | - Alpine.js: https://alpinejs.dev/
129 | - Turso: https://docs.turso.tech/
130 |
--------------------------------------------------------------------------------
/.env.example:
--------------------------------------------------------------------------------
1 | # Astro DB - LibSQL (required) - Your database - https://docs.astro.build/en/guides/astro-db/#connect-a-libsql-database-for-production
2 | ASTRO_DB_REMOTE_URL=""
3 | ASTRO_DB_APP_TOKEN=""
4 |
5 | # Better Auth (required) - https://www.better-auth.com/docs/installation#set-environment-variables
6 | BETTER_AUTH_SECRET=""
7 | BETTER_AUTH_URL="http://localhost:4321"
8 | BETTER_AUTH_EMAIL_VERIFICATION="false"
9 |
10 | # Mail server configuration
11 | MAIL_HOST=smtp.resend.com
12 | MAIL_PORT=465
13 | MAIL_SECURE=true
14 | MAIL_AUTH_USER=resend
15 | MAIL_AUTH_PASS=your_resend_api_key
16 | MAIL_FROM=your_verified_sender@yourdomain.com
17 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # build output
2 | dist/
3 |
4 | # generated types
5 | .astro/
6 |
7 | # dependencies
8 | node_modules/
9 |
10 | # logs
11 | npm-debug.log*
12 | yarn-debug.log*
13 | yarn-error.log*
14 | pnpm-debug.log*
15 |
16 | # Package managers file
17 | pnpm-lock.yaml
18 |
19 | # environment variables
20 | .env
21 | .env.production
22 |
23 | # macOS-specific files
24 | .DS_Store
25 |
26 | # Netlify build
27 | .netlify/
28 |
29 | # TinyMCE self-hosted gets copied on build, so no need to commit.
30 | public/tinymce/
31 |
32 | # Ignore all versions of tinymce in the specified path
33 | node_modules/.pnpm/tinymce@*/node_modules/tinymce
34 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | .git
2 | .github
3 | .DS_Store
4 | node_modules
5 | dist
6 | .env
7 | .env.*
8 | !.env.example
9 | .vscode
10 | .astro
11 | .netlify
12 | *.log
13 |
--------------------------------------------------------------------------------
/.nvmrc:
--------------------------------------------------------------------------------
1 | 20.10.0
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "useTabs": false,
3 | "trailingComma": "none",
4 | "printWidth": 120,
5 | "tabWidth": 2,
6 | "plugins": ["prettier-plugin-astro"],
7 | "overrides": [
8 | {
9 | "files": "*.astro",
10 | "options": {
11 | "parser": "astro"
12 | }
13 | }
14 | ]
15 | }
16 |
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": [
3 | "astro-build.astro-vscode",
4 | "RisingStack.astro-alpinejs-syntax-highlight",
5 | "CraigRBroughton.htmx-attributes",
6 | "esbenp.prettier-vscode"
7 | ],
8 | "unwantedRecommendations": []
9 | }
10 |
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "0.2.0",
3 | "configurations": [
4 | {
5 | "command": "./node_modules/.bin/astro dev",
6 | "name": "Development server",
7 | "request": "launch",
8 | "type": "node-terminal"
9 | }
10 | ]
11 | }
12 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "editor.formatOnSave": true,
3 | "editor.defaultFormatter": "esbenp.prettier-vscode",
4 | "editor.tabSize": 2,
5 | "editor.insertSpaces": true,
6 | "files.trimTrailingWhitespace": true,
7 | "files.insertFinalNewline": true,
8 | "prettier.requireConfig": true,
9 | "[astro]": {
10 | "editor.defaultFormatter": "astro-build.astro-vscode"
11 | },
12 | "[xml]": {
13 | "editor.defaultFormatter": "redhat.vscode-xml"
14 | },
15 | "typescript.tsdk": "node_modules/typescript/lib",
16 | "typescript.enablePromptUseWorkspaceTsdk": true,
17 | "editor.rulers": [120],
18 | "files.associations": {
19 | "*.mdx": "markdown"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | Freedom Stack is committed to being a welcoming community that empowers developers to create with freedom and joy. We pledge to make participation in our project and community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
6 |
7 | ## Our Values
8 |
9 | - **Approachability**: We believe in making web development accessible to everyone, regardless of their experience level. We welcome questions, encourage learning, and support those new to our stack.
10 |
11 | - **Flow-ability**: We value simplicity and focus. Our community interactions should reflect this by being clear, helpful, and free from unnecessary complexity or gatekeeping.
12 |
13 | - **Pocket-friendly**: We work hard to make full-stack web development financially accessible to everyone.
14 |
15 | - **Generosity**: We believe that it is better to give than to receive, a lesson taught by Jesus in the Bible. While this project is created by a Christian, anyone can contribute to this project.
16 |
17 | ## Expected Behavior
18 |
19 | - Use welcoming and kind language
20 | - Be respectful to one another
21 | - Gracefully accept constructive criticism
22 | - Focus on what is best for the community
23 | - Show empathy towards other community members
24 | - Help others learn and grow
25 |
26 | ## Unacceptable Behavior
27 |
28 | The following behaviors are considered harassment and are unacceptable:
29 |
30 | - The use of sexualized language or imagery
31 | - Personal attacks or derogatory comments
32 | - Public or private harassment
33 | - Publishing others' private information without explicit permission
34 | - Other conduct which could reasonably be considered inappropriate in a professional setting
35 | - Trolling, insulting/derogatory comments, and personal or political attacks
36 | - Promoting discrimination of any kind
37 |
38 | ## Enforcement Responsibilities
39 |
40 | Project maintainers are responsible for clarifying and enforcing standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful.
41 |
42 | ## Reporting Process
43 |
44 | If you experience or witness unacceptable behavior, please report it by:
45 |
46 | 1. Opening an issue in the repository
47 | 2. Contacting the project maintainers directly
48 | 3. Emailing [Cameron Pak](https://letterbird.co/cameronandrewpak)
49 |
50 | All complaints will be reviewed and investigated promptly and fairly. All community leaders are obligated to respect the privacy and security of the reporter of any incident.
51 |
52 | ## Enforcement
53 |
54 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned with this Code of Conduct. Project maintainers who do not follow or enforce the Code of Conduct may be temporarily or permanently removed from the project team.
55 |
56 | ## Attribution
57 |
58 | This Code of Conduct is adapted from the [Project Include](https://projectinclude.org/writing_cocs) guidelines and inspired by the [Contributor Covenant](https://www.contributor-covenant.org/), version 2.0.
59 |
60 | ## Questions?
61 |
62 | If you have questions about this Code of Conduct, please open an issue in the repository or contact the project maintainers.
63 |
64 | ## Project Maintenance
65 |
66 | This project is maintained by Cameron Pak as the sole maintainer, operating under FAITH TOOLS SOFTWARE SOLUTIONS, LLC. While community contributions are welcome, final decisions and project direction are managed through this structure.
67 |
68 | ---
69 |
70 | Freedom Stack is made with 🕊️ by [Cameron Pak](https://cameronpak.com), brought to you by [faith.tools](https://faith.tools).
71 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024 Cameron Pak, FAITH TOOLS SOFTWARE SOLUTIONS, LLC
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Freedom Stack
2 |
3 | > [!WARNING]
4 | > Freedom Stack is no longer in active development and needs maintainers/contributors! If you want to be part of this, [email me](mailto:cameronandrewpak@gmail.com?subject=I%20want%20to%20contribute%20to%20Freedom%20Stack)
5 |
6 | > [!IMPORTANT]
7 | > I'd recommend checking out [Better T Stack](https://better-t-stack.amanv.dev/new) to piece together your preferred app stack.
8 |
9 | A modern, type-safe web development stack using Astro, TypeScript, HTMX, Alpine.js, and more.
10 |
11 | > [!TIP]
12 | > Turso has a generous free tier for database hosting and management. And, when it's time to scale, use the code `FREEDOMSTACK` for a discount on paid plans.
13 | > [Check out Turso](https://tur.so/freedomstack)
14 |
15 | ## Get Started 🚀
16 |
17 | ### 1. Create Your Project
18 |
19 | You can create a new Freedom Stack project using npm:
20 |
21 | ```bash
22 | # Create a new project
23 | npx create-freedom-stack my-app
24 |
25 | # Navigate to the project directory
26 | cd my-app
27 |
28 | # Set up your database
29 | npm run db:setup
30 |
31 | # Start the development server
32 | npm run dev
33 | ```
34 |
35 | Your development server will be running on [`localhost:4321`](http://localhost:4321).
36 |
37 | ### 2. Environment Variables
38 |
39 | The project will automatically create a `.env` file with a generated `BETTER_AUTH_SECRET`. You'll need to set these additional variables:
40 |
41 | ```env
42 | # Astro DB - LibSQL (required) - Your database
43 | ASTRO_DB_REMOTE_URL="" # Added by npm run db:setup
44 | ASTRO_DB_APP_TOKEN="" # Added by npm run db:setup
45 |
46 | # Better Auth (required)
47 | BETTER_AUTH_SECRET="" # Auto-generated during setup
48 | BETTER_AUTH_URL="http://localhost:4321"
49 |
50 | # Email Configuration (optional) - For sending emails
51 | MAIL_HOST="" # SMTP host (e.g., smtp.resend.com)
52 | MAIL_PORT="" # SMTP port (e.g., 465)
53 | MAIL_SECURE="" # Use TLS/SSL (true/false)
54 | MAIL_AUTH_USER="" # SMTP username
55 | MAIL_AUTH_PASS="" # SMTP password or API key
56 | MAIL_FROM="" # Sender email address
57 | ```
58 |
59 | ### 3. Have fun!
60 |
61 | Create because you love creating. Make development fun again!
62 |
63 | ## What's Included
64 |
65 | - 🚀 [Astro](https://astro.build) - The web framework for content-driven websites
66 | - 🎨 [TailwindCSS](https://tailwindcss.com) + [DaisyUI](https://daisyui.com) - Utility-first CSS
67 | - ⚡ [HTMX](https://htmx.org) - High power tools for HTML
68 | - 🗄️ [Astro DB](https://docs.astro.build/en/guides/astro-db) - Built-in database with type safety
69 | - 🔒 [Better Auth](https://better-auth.com) - Simple, secure authentication
70 | - 🏃♂️ [Alpine.js](https://alpinejs.dev) - Lightweight JavaScript framework
71 |
72 | # Freedom Stack • Full-Stack Starter Kit
73 |
74 | [](https://app.netlify.com/sites/freedom-stack/deploys) [](https://github.com/cameronapak/freedom-stack/stargazers)
75 |
76 | An Astro-based full-stack starter kit that feels freeing, and is free. Make development fun again. [See the demo site](https://freedom.faith.tools).
77 |
78 | I wanted to provide a stack that's powerful like Ruby on Rails _("The One Person Framework")_, but with the ease and "vanilla" web dev feel of Astro.
79 |
80 |
81 |
82 | 
83 |
84 | ## Learning Resources 📚
85 |
86 | ### The Frontend Layer
87 |
88 | If you want to learn more about the frontend layer, I recommend the [Astro Web Framework Crash Course by freeCodeCamp](https://www.youtube.com/watch?v=e-hTm5VmofI).
89 |
90 | ### The Interactivity Layer
91 |
92 | If you want to learn more about Alpine.js, I recommend [Learn Alpine.js on codecourse](https://codecourse.com/courses/learn-alpine-js).
93 |
94 | ### The Database Layer
95 |
96 | If you want to learn more about the database layer, I recommend learning from [High Performance SQLite course](https://highperformancesqlite.com/), sponsored by [Turso](https://tur.so/freedomstack/).
97 |
98 | ### The Philosophy Layer
99 |
100 | A starter kit like this can save hours, days, or even weeks of development time. However, it's not enough just to have the baseline. You will need to have a philosophy around building a site or web app, so that you can make the most of the tooling and minimize wasting time. I recommend reading Getting Real by 37signals. [It's free to read online](https://books.37signals.com/8/getting-real). _(While the book says a few choice words, it's a great, practical resource for building great software.)_
101 |
102 | ## Here's What's Included 🔋🔋🔋
103 |
104 | Ogres have layers. Onions have layers. Parfaits have layers. And, Freedom Stack has layers!
105 |
106 | ### UI Layer
107 |
108 | - [Astro](https://astro.build/) - A simple web metaframework.
109 | - [Tailwind CSS](https://tailwindcss.com/) - For styling.
110 | - [Preline UI](https://preline.co/) - Tailwind-based HTML components.
111 | - [Daisy UI](https://daisyui.com/) - For a Bootstrap-like UI CSS component
112 | library, built upon Tailwind.
113 | - [Lucide Icons](https://lucide.dev/) - For a beautiful icon library.
114 |
115 | ### Interactivity Layer
116 |
117 | - [TypeScript](https://www.typescriptlang.org/) - For type safety.
118 | - [AlpineJS](https://alpinejs.dev/) - For state management and interactivity.
119 | - [HTMX](https://htmx.org/) - For sending HTML partials/snippets over the wire.
120 |
121 | ### Backend Data Layer
122 |
123 | - [Astro DB](https://astro.build/db) - Astro DB is a fully managed SQL database
124 | that is fast, lightweight, and ridiculously easy-to-use.
125 | - [Drizzle ORM](https://orm.drizzle.team/) - Use your database without having to know or worry about SQL syntax.
126 | - [Better Auth](https://better-auth.com/) - For authentication.
127 |
128 | ### Bonus Layer
129 |
130 | - A well-prompted `.cursorrules` file for [Cursor's AI IDE](https://cursor.com/) to be a friendly guide helping you using this stack easier.
131 |
132 | ---
133 |
134 | ## Host Your Project ☁️
135 |
136 | Host your site with [Netlify](https://netlify.com) in under a minute.
137 |
138 | First, you must login to Netlify:
139 |
140 | ```bash
141 | npm run host:login
142 | ```
143 |
144 | Then, you can deploy your site with:
145 |
146 | ```bash
147 | npm run host:deploy
148 | ```
149 |
150 | > [!IMPORTANT]
151 | > Remember to set the environment variables in Netlify so that it builds successfully.
152 |
153 | [Learn more about hosting Astro sites on Netlify](https://docs.astro.build/en/guides/deploy/netlify/).
154 |
155 | ---
156 |
157 | ## Send Emails
158 |
159 | ## Email Configuration 📧
160 |
161 | Freedom Stack includes a pre-configured email service using Nodemailer. This allows you to:
162 |
163 | - Send transactional emails
164 | - Use any SMTP provider
165 | - Handle email templates
166 | - Maintain type safety
167 |
168 | ### Setting up Email
169 |
170 | 1. Configure your environment variables as shown above
171 |
172 | Send emails programmatically:
173 |
174 | ```typescript
175 | import { sendEmail } from "@/lib/email";
176 |
177 | await sendEmail({
178 | to: "recipient@example.com",
179 | subject: "Hello!",
180 | html: "
Welcome!
"
181 | });
182 | ```
183 |
184 | ### Email Providers
185 |
186 | While you can use any SMTP provider, we recommend [Resend](https://resend.com) - Modern email API with generous free tier.
187 |
188 | > [!TIP]
189 | > Resend offers 100 emails/day free and has excellent developer experience.
190 |
191 | ---
192 |
193 | ## Vision ❤️
194 |
195 | I dream of a lightweight, simple web development stack that invokes a fun web
196 | experience at the cheapest possible maintainance, backend, and server cost. As
197 | close to free as possible.
198 |
199 | ### Core Principles
200 |
201 | - **Approachable** — I want those new to web development to feel comfortable
202 | using this stack. Things like database management should feel intuitive.
203 | Remove barriers of traditional JavaScript frameworks, such as excessive
204 | boilerplate code or intense state management. Go back to the basics of web
205 | development. (_While this is not vanilla, the dev experience will feel very
206 | natural._)
207 | - **Flow-able** — Use an HTML-first approach, where almost all of the work is
208 | done on the DOM layer: styling, structuring, and interactivity. An opinionated
209 | stack helps you avoid analysis paralysis of trying to decide what tooling to
210 | pick or how to put things together. Instead, spend your thinking time
211 | building. This simple stack helps you focus and get in the flow of code
212 | faster. Fast setup. Fast building. Fast shipping.
213 | - **Pocket-friendly** — Using this stack will be financially maintainable to
214 | anyone, especially indie hackers and those creating startup sites / web apps.
215 |
216 | ## Showcase 🏆
217 |
218 | - [faith.tools](https://faith.tools)
219 | - [freedom](https://freedom.melos.church)
220 | - [Be Still](https://ft-be-still.netlify.app)
221 | - [kit](https://kit.faith.tools)
222 |
223 | Have a project that uses Freedom Stack? [Open a PR](https://github.com/cameronapak/freedom-stack) to add it to the list!
224 |
225 | ## Available Scripts ⚡
226 |
227 | | Command | Description |
228 | | --------------------------- | ------------------------------------------------ |
229 | | `npm run dev` | Start the development server |
230 | | `npm run dev:host` | Start development server accessible from network |
231 | | `npm run build` | Build the production site with remote database |
232 | | `npm run preview` | Preview the built site locally |
233 | | `npm run format` | Format all files using Prettier |
234 | | `npm run packages:update` | Update all packages to their latest versions |
235 | | `npm run db:update-schemas` | Push database schema changes to remote database |
236 |
237 | ## Contributions 🤝
238 |
239 | Contributions welcomed. Please
240 | [open an issue](https://github.com/cameronapak/astwoah-stack/issues) if you'd
241 | like to contribute.
242 |
243 |
244 |
245 |
246 |
247 | Made with [contrib.rocks](https://contrib.rocks).
248 |
249 | ---
250 |
251 | ## License 📜
252 |
253 | This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
254 |
255 | ## Code of Conduct 📜
256 |
257 | See the [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) file for details.
258 |
259 | ---
260 |
261 | Freedom Stack is made with 🕊️ by [Cameron Pak](https://cameronpak.com), brought to you by [faith.tools](https://faith.tools).
262 |
--------------------------------------------------------------------------------
/astro.config.mjs:
--------------------------------------------------------------------------------
1 | import { defineConfig } from "astro/config";
2 | import tailwindcss from "@tailwindcss/vite";
3 | import alpinejs from "@astrojs/alpinejs";
4 | import netlify from "@astrojs/netlify";
5 | import db from "@astrojs/db";
6 |
7 | // https://astro.build/config
8 | export default defineConfig({
9 | integrations: [
10 | db(),
11 | alpinejs({
12 | entrypoint: "/src/entrypoint"
13 | })
14 | ],
15 | output: "server",
16 | adapter: netlify(),
17 | vite: {
18 | plugins: [tailwindcss()]
19 | }
20 | });
21 |
--------------------------------------------------------------------------------
/db/config.ts:
--------------------------------------------------------------------------------
1 | import { defineDb, defineTable, column } from "astro:db";
2 |
3 | const Posts = defineTable({
4 | columns: {
5 | id: column.number({ primaryKey: true }),
6 | title: column.text(),
7 | pubDate: column.date(),
8 | description: column.text(),
9 | author: column.text(),
10 | imageUrl: column.text({ optional: true }),
11 | imageAlt: column.text({ optional: true }),
12 | tags: column.json({ optional: true }),
13 | slug: column.text({ unique: true }),
14 | content: column.text()
15 | }
16 | });
17 |
18 | const User = defineTable({
19 | columns: {
20 | id: column.text({ primaryKey: true }),
21 | email: column.text({ unique: true }),
22 | name: column.text(),
23 | emailVerified: column.boolean({ default: false }),
24 | image: column.text({ optional: true }),
25 | createdAt: column.date(),
26 | updatedAt: column.date()
27 | }
28 | });
29 |
30 | const Session = defineTable({
31 | columns: {
32 | token: column.text(),
33 | id: column.text({ primaryKey: true }),
34 | userId: column.text(),
35 | expiresAt: column.date(),
36 | ipAddress: column.text({ optional: true }),
37 | userAgent: column.text({ optional: true }),
38 | createdAt: column.date(),
39 | updatedAt: column.date()
40 | }
41 | });
42 |
43 | const Account = defineTable({
44 | columns: {
45 | id: column.text({ primaryKey: true }),
46 | userId: column.text(),
47 | accountId: column.text({ optional: true }),
48 | providerId: column.text({ optional: true }),
49 | accessToken: column.text({ optional: true }),
50 | refreshToken: column.text({ optional: true }),
51 | idToken: column.text({ optional: true }),
52 | expiresAt: column.date({ optional: true }),
53 | password: column.text({ optional: true }),
54 | createdAt: column.date(),
55 | updatedAt: column.date()
56 | }
57 | });
58 |
59 | const Verification = defineTable({
60 | columns: {
61 | id: column.text({ primaryKey: true }),
62 | identifier: column.text(),
63 | value: column.text(),
64 | expiresAt: column.date(),
65 | createdAt: column.date(),
66 | updatedAt: column.date({ optional: true })
67 | }
68 | });
69 |
70 | export default defineDb({
71 | tables: {
72 | Posts,
73 | User,
74 | Session,
75 | Account,
76 | Verification
77 | }
78 | });
79 |
--------------------------------------------------------------------------------
/db/seed.ts:
--------------------------------------------------------------------------------
1 | import { db, Posts } from "astro:db";
2 |
3 | const content = `
4 | ## This is the first post of my new Astro blog.
5 |
6 | Never gonna give you up, never gonna let you down.
7 | Never gonna run around and desert you.
8 | Never gonna make you cry, never gonna say goodbye.
9 | Never gonna tell a lie and hurt you.
10 | Never gonna hold you back, never gonna lose your grip.
11 | Never gonna give you up, never gonna let you down.
12 | Never gonna run around and desert you.
13 | Never gonna make you cry, never gonna say goodbye.
14 | Never gonna tell a lie and hurt you.
15 | `.trim();
16 |
17 | const shrekContent = `
18 |
A Story of Layers
19 |
20 |
21 | Just like onions, this blog post has layers. Shrek taught us that true beauty lies within,
22 | and that the best stories often come from the most unexpected places - like a swamp.
23 |
24 |
25 |
26 | Some people judge a book by its cover, but as our favorite ogre would say, "Better out than in!"
27 | This post celebrates the wisdom, humor, and heart that made Shrek a beloved character for generations.
28 |
29 |
30 |
31 | Remember: Ogres are like onions. They have layers. Onions have layers.
32 |
137 |
138 | {
139 | /* The prose class from @tailwindcss/typography plugin provides beautiful typographic defaults for HTML content like articles, blog posts, and documentation. It styles headings, lists, code blocks, tables etc. */
140 | }
141 |
60 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/src/pages/index.astro:
--------------------------------------------------------------------------------
1 | ---
2 | import Layout from "@/layouts/Layout.astro";
3 | import HalfTextHalfImage from "@sections/HalfTextHalfImage.astro";
4 | import Quote from "@sections/Quote.astro";
5 | import Navbar from "@sections/Navbar.astro";
6 | import Footer from "@sections/Footer.astro";
7 | import Features from "@sections/Features/index.astro";
8 | import Container from "@sections/Container.astro";
9 | import FAQ from "@sections/FAQ.astro";
10 | import RenderMarkdown from "@/components/RenderMarkdown.astro";
11 | import GithubButton from "@/components/server/GithubButton.astro";
12 | import sectionsImage from "@/assets/sections.png";
13 | import deployToNetlifyImage from "@/assets/deploy.png";
14 | import fullStackImage from "@/assets/full-stack.png";
15 |
16 | const features = [
17 | { title: "Astro", description: "The simplest web metaframework" },
18 | { title: "Alpine.js", description: "Used for client-side interactivity" },
19 | { title: "HTMX", description: "HTML over the wire (see htmx.org)" },
20 | { title: "daisyUI", description: "Easy as Bootstrap; built upon Tailwind" },
21 | { title: "Better Auth", description: "Comprehensive TS auth framework" },
22 | { title: "Astro DB", description: "An approachable database solution" },
23 | { title: "NodeMailer", description: "Send emails easily via SMTP" }
24 | ];
25 |
26 | const faqItems = [
27 | {
28 | question: "What is Freedom Stack?",
29 | answer: "Freedom Stack is a full-stack Astro starter kit that feels freeing and is free."
30 | },
31 | {
32 | question: "How can I learn more about Astro?",
33 | answer:
34 | "If you want to learn more about the frontend layer, I recommend the [Astro Web Framework Crash Course by freeCodeCamp](https://www.youtube.com/watch?v=e-hTm5VmofI) or check out [Astro's Community Educational Content](https://docs.astro.build/en/community-resources/content/)."
35 | },
36 | {
37 | question: "How can I learn more about Alpine.js?",
38 | answer:
39 | "If you want to learn more about Alpine.js, I recommend [Learn Alpine.js on codecourse](https://codecourse.com/courses/learn-alpine-js?ref=freedomstack)."
40 | },
41 | {
42 | question: "How can I learn more about the libSQL database layer?",
43 | answer:
44 | "If you want to learn more about the database layer, I recommend first starting with Astro DB's [Getting Started Guide](https://docs.astro.build/en/guides/astro-db/?ref=freedomstack), and then learning from [High Performance SQLite course](https://highperformancesqlite.com/?ref=freedomstack), sponsored by [Turso](https://tur.so/freedomstack)."
45 | },
46 | {
47 | question: "How can I learn more about Better Auth?",
48 | answer: "[Learn more about Better Auth.](https://www.better-auth.com/docs/integrations/astro?ref=freedomstack)"
49 | },
50 | {
51 | question: "How do I deploy Freedom Stack?",
52 | answer:
53 | "You can deploy Freedom Stack to [Netlify](https://app.netlify.com/start/deploy?repository=https://github.com/cameronapak/freedom-stack)."
54 | },
55 | {
56 | question: "How can I learn more about HTMX?",
57 | answer: "[Learn more about HTMX.](https://htmx.org/?ref=freedomstack)"
58 | },
59 | {
60 | question: "How can I learn more about daisyUI?",
61 | answer: "[Learn more about daisyUI.](https://daisyui.com/?ref=freedomstack)"
62 | },
63 | {
64 | question: "What's an affordable way to track my website's traffic/analytics?",
65 | answer:
66 | "I recommend [One Dollar Stats, by Drizzle](https://onedollarstats.com/?ref=freedomstack), or try out [PostHog](https://posthog.com/?ref=freedomstack)."
67 | },
68 | {
69 | question: "How can I contribute to Freedom Stack?",
70 | answer:
71 | "If you'd like to contribute to Freedom Stack, please [open an issue](https://github.com/cameronapak/freedom-stack/issues) or [submit a pull request](https://github.com/cameronapak/freedom-stack/pulls). Or, if you can submit financially, please consider [buying me a coffee](https://buymeacoffee.com/campak)."
72 | }
73 | ];
74 |
75 | const letterContentMarkdown = `
76 | Hey, I'm Cam, a front-end designer and developer of over 7 years.
77 |
78 | While I loved working on the UI, animations, and interactivity of web apps, I'd always felt held back by not knowing how to
79 | create full-stack web apps.
80 |
81 | I knew how to work with API's and someone else's database, but I'd never learned how to build my own until...
82 |
83 | _A wild [Astro DB](https://docs.astro.build/en/guides/astro-db/) enters the chat!_
84 |
85 | Astro combined one of the easiest to use database layers and made it even easier with [Drizzle ORM](https://orm.drizzle.team/).
86 |
87 | I found myself building full-stack web apps without really having to think too much about databases. They just worked.
88 |
89 | Writing code felt freeing and fun again.
90 |
91 | I got this spark and reinvoration to code again after the hardest season of my life, when I was bed-ridden for around seven months. [God](https://www.gotquestions.org/what-is-the-gospel.html) sustained me through
92 | the support of friends and family. He healed me spiritually before physically restoring my health.
93 |
94 | After recovering, I finally felt freedom.
95 |
96 | My hope is that Freedom Stack empowers you to create the dreams and visions on your mind and heart.
97 |
98 | _— [Cam Pak](https://cameronpak.com)_
99 | `;
100 |
101 | // The browser should always check freshness
102 | Astro.response.headers.set("cache-control", "public, max-age=0, must-revalidate");
103 |
104 | // The CDN should cache for a year, but revalidate if the cache tag changes
105 | Astro.response.headers.set("netlify-cdn-cache-control", "s-maxage=31536000");
106 |
107 | // Tag the page with the project slug
108 | Astro.response.headers.set("netlify-cache-tag", "components");
109 | ---
110 |
111 |
115 |
122 |
123 |
124 |
125 |
126 |
---------------
127 |
128 |
129 |
Freedom Stack
130 |
A full-stack Astro starter kit that feels freeing and is free.