Galactic Archives - Basic Project Setup
June 1, 2025
Angular DataSource with SWAPI: Building the Galactic Archives - Basic Project Setup
In a universe where frameworks multiply faster than tribbles on a grain barge, setting up a new Angular project remains a ritual as ancient as the first npm install
. Some say the Ancient Order of Angular created the CLI during a particularly productive full moon, while others insist it emerged fully formed from a quantum fluctuation in the npm registry.
The Foundation of Our Galactic Archives
Before we can build our magnificent Star Wars data explorer, we need to establish a base of operations. Like any good rebel outpost, our project requires proper infrastructure, defensive shields (error handling), and a sleek command center (UI).
The Cosmic Compiler watches with interest as we lay the groundwork for what will become the most comprehensive archive of galactic data this side of the Outer Rim.
Creating a New Angular Project
Let's summon the power of the Angular CLI to create our project:
# Invoke the ancient incantation to create a new Angular project with version 18
# The Cosmic Compiler appreciates descriptive project names
npm i -g @angular/[email protected]
ng new galactic-archives --routing --style=scss --skip-tests=false --strict --standalone
# Navigate to the newly created dimensional pocket
cd galactic-archives
When prompted, answer "Yes" to Angular routing (we'll need hyperspace travel between components) and select SCSS as the stylesheet format (the Galactic Standards Committee strongly prefers it over plain CSS).
Project Structure
The CLI has conjured a basic project structure for us, but we'll need to adapt it to follow the feature-based architecture prophecied in the TypeScript Prophecies:
galactic-archives/
├── src/
│ ├── app/
│ │ ├── app.routes.ts // Standalone routing configuration
│ │ ├── app.config.ts // Application configuration and providers
│ │ ├── app.component.html
│ │ ├── app.component.scss
│ │ └── app.component.ts // Standalone component
│ ├── assets/
│ ├── main.ts // Application bootstrap
│ └── index.html
├── angular.json
├── package.json
└── tsconfig.json
Installing Angular Material
No self-respecting galactic archive would be caught without the sleek, professional components of Angular Material. Let's add this to our arsenal:
# Summon the Material design entities to our dimension
ng add @angular/material
When prompted:
- Choose a theme (I recommend "Custom" for our Star Wars theme later)
- Select "Yes" for Angular Material typography
- Select "Yes" for browser animations
The Material setup wizard is like a helpful protocol droid—slightly annoying but ultimately saving you from hours of manual configuration.
Adding Tailwind CSS
While Material provides excellent components, Tailwind CSS gives us the utility-first approach that the Council of Patterns has been advocating for eons. By prefixing Tailwind classes with tw-
, we avoid conflicts with Material's styles while maintaining a clear separation of concerns. Material handles the complex components like tables and dialogs, while Tailwind handles spacing, colors, and responsive design without writing custom CSS. This combination lets us rapidly prototype layouts directly in templates while keeping our bundle size smaller by avoiding unnecessary custom styles. The Cosmic Compiler particularly appreciates this organized approach.
Here's a practical example of how Material and Tailwind work together in a component:
<!-- Character card component using both Material and Tailwind -->
<mat-card
class="tw-mb-4 tw-transition-all tw-duration-300 tw-hover:tw-shadow-xl"
>
<mat-card-header>
<mat-card-title class="tw-text-xl tw-font-bold tw-text-primary"
>{{ character.name }}</mat-card-title
>
<mat-card-subtitle class="tw-text-secondary"
>{{ character.species }}</mat-card-subtitle
>
</mat-card-header>
<mat-card-content class="tw-py-2">
<div class="tw-grid tw-grid-cols-2 tw-gap-2">
<div class="tw-text-sm">
<strong>Height:</strong> {{ character.height }}cm
</div>
<div class="tw-text-sm">
<strong>Mass:</strong> {{ character.mass }}kg
</div>
</div>
</mat-card-content>
<mat-card-actions class="tw-flex tw-justify-end">
<button mat-button color="primary" class="tw-font-medium">
VIEW DETAILS
</button>
<button mat-icon-button class="tw-ml-2">
<mat-icon>favorite_border</mat-icon>
</button>
</mat-card-actions>
</mat-card>
In this example, we're using Material's mat-card
component structure while enhancing it with Tailwind's utility classes for spacing, transitions, hover effects, grid layout, and text styling - all without writing a single line of custom CSS.
# Install Tailwind CSS and its dependencies
npm install -D tailwindcss postcss autoprefixer
# Initialize Tailwind CSS configuration
npx tailwindcss init
Now, let's configure Tailwind to work with our Angular project. Create or update the following files:
// tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
prefix: "tw-", // The Galactic Standards Committee requires prefixing to avoid conflicts
content: [
"./src/**/*.{html,ts}", // Scan all our HTML and TypeScript files
],
theme: {
extend: {
// We'll add our Star Wars theme colors later
// The Void of Undefined currently occupies this space
},
},
plugins: [],
};
Next, update your src/styles.scss
file:
/* You can add global styles to this file, and also import other style files */
@tailwind base;
@tailwind components;
@tailwind utilities;
// The Ancient Order of Angular recommends keeping global styles minimal
// Most styling should be component-specific or utility-based
Creating a Basic App Shell
Now, let's create a simple app shell with a header and footer. This will serve as the command center for our Galactic Archives:
// app.component.ts
import { Component } from "@angular/core";
@Component({
selector: "app-root",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.scss"],
})
export class AppComponent {
title = "Galactic Archives"; // The name of our noble endeavor
// The Cosmic Compiler appreciates well-named methods
getCurrentYear(): number {
return new Date().getFullYear(); // Time is an illusion, but copyright dates are not
}
}
Update the HTML template:
<!-- app.component.html -->
<div class="tw-flex tw-flex-col tw-min-h-screen">
<!-- Header: Command center of our application -->
<header class="tw-bg-gray-900 tw-text-white tw-p-4 tw-shadow-md">
<div
class="tw-container tw-mx-auto tw-flex tw-justify-between tw-items-center"
>
<h1 class="tw-text-xl tw-font-bold">{{ title }}</h1>
<nav>
<!-- Navigation will be added in a future episode -->
<!-- The Inevitable Refactor looms on the horizon -->
</nav>
</div>
</header>
<!-- Main content area: Where the magic happens -->
<main class="tw-container tw-mx-auto tw-flex-grow tw-p-4">
<!-- Router outlet: A portal to other dimensions (components) -->
<router-outlet></router-outlet>
</main>
<!-- Footer: Every good application needs a footer -->
<footer class="tw-bg-gray-900 tw-text-white tw-p-4 tw-mt-auto">
<div class="tw-container tw-mx-auto tw-text-center">
<p>
© {{ getCurrentYear() }} Galactic Archives | Built with Angular by the
Rebel Alliance
</p>
</div>
</footer>
</div>
Setting Up Standalone Components
Angular v18 uses the standalone components approach, which is a significant shift from the previous NgModule-based architecture. In the old days (pre-v14), components had to be declared in an NgModule before they could be used, creating a complex web of module dependencies that often led to what the Ancient Order called "ModuleMadness™".
With standalone components, each component declares its own dependencies directly, eliminating the need for NgModules in many cases. This means:
- No more
declarations
arrays listing every component - No more importing feature modules just to use a single component
- Direct imports of the components you need, when you need them
- Simpler lazy-loading without module wrappers
Instead of having an AppModule
with declarations, imports, and providers, we now have a more streamlined approach with app.config.ts
handling application-wide providers and each component managing its own dependencies.
Let's update our app.component.ts
to use the standalone approach and create a proper app.config.ts
:
// app.component.ts
import { Component } from "@angular/core";
import { RouterOutlet } from "@angular/router";
// Import basic Material modules
// The Ancient Order of Angular recommends importing only what you need
import { MatToolbarModule } from "@angular/material/toolbar";
import { MatButtonModule } from "@angular/material/button";
import { MatIconModule } from "@angular/material/icon";
@Component({
selector: "app-root",
standalone: true, // The Cosmic Compiler rejoices at standalone components
imports: [RouterOutlet, MatToolbarModule, MatButtonModule, MatIconModule],
templateUrl: "./app.component.html",
styleUrls: ["./app.component.scss"],
})
export class AppComponent {
title = "Galactic Archives"; // The name of our noble endeavor
// The Cosmic Compiler appreciates well-named methods
getCurrentYear(): number {
return new Date().getFullYear(); // Time is an illusion, but copyright dates are not
}
}
Now, let's create the application configuration file that sets up providers and bootstraps our app:
// app.config.ts
import { ApplicationConfig } from "@angular/core";
import { provideRouter } from "@angular/router";
import { provideAnimations } from "@angular/platform-browser/animations";
import { routes } from "./app.routes";
export const appConfig: ApplicationConfig = {
providers: [
provideRouter(routes),
provideAnimations(), // The Ancient Order requires animations for a proper UI experience
],
};
Finally, let's update the main.ts
file to bootstrap our application:
// main.ts
import { bootstrapApplication } from "@angular/platform-browser";
import { appConfig } from "./app/app.config";
import { AppComponent } from "./app/app.component";
bootstrapApplication(AppComponent, appConfig).catch((err) =>
console.error("The Cosmic Compiler encountered an error:", err)
);
Running the Application
With our basic setup complete, let's fire up the hyperdrive and see our creation:
# Launch the application into development space
ng serve --open
If all goes well (and the Dependency Demons haven't been messing with your node_modules), your browser should open to http://localhost:4200
displaying our basic Galactic Archives shell.
Cosmic Compiler Summary
- We've created a new Angular project using the CLI, the preferred tool of the Ancient Order of Angular
- We've installed Angular Material for sleek, professional UI components
- We've added Tailwind CSS for utility-first styling with the
tw-
prefix to avoid conflicts - We've created a basic app shell with header and footer using our new tools
- We've set up the foundation for our feature-based architecture
In our next transmission, we'll establish proper code quality standards with ESLint and Prettier. The Galactic Standards Committee has been known to dispatch inspectors without warning, so we'd best be prepared. As the Recursive Philosopher says, "Good code is its own documentation, but good documentation is... good code?"
May your builds be swift and your runtime errors few.