# How Filter Files Are Generated and Maintained in awesome-free-apps

> Discover how awesome-free-apps generates and maintains filter files using an automated Node.js script. Learn how README and MOBILE files are parsed to create organized lists.

- Repository: [Axorax/awesome-free-apps](https://github.com/Axorax/awesome-free-apps)
- Tags: how-to-guide
- Published: 2026-05-26

---

**The filter files in Axorax/awesome-free-apps are automatically generated by a Node.js script that parses [`README.md`](https://github.com/Axorax/awesome-free-apps/blob/main/README.md) and [`MOBILE.md`](https://github.com/Axorax/awesome-free-apps/blob/main/MOBILE.md), extracting entries based on emoji markers and writing them to the `filter/` directory.**

The Axorax/awesome-free-apps repository maintains curated lists of free software across multiple platforms. Instead of manually editing separate markdown files for each category, the project uses an automated build system to generate filter files like [`open-source-only.md`](https://github.com/Axorax/awesome-free-apps/blob/main/open-source-only.md) and [`windows-only.md`](https://github.com/Axorax/awesome-free-apps/blob/main/windows-only.md) directly from the master lists.

## The Core Generation Process

The generation logic lives in [`index.js`](https://github.com/Axorax/awesome-free-apps/blob/main/index.js) at the repository root. The script reads the source markdown files line-by-line and reconstructs category-specific versions based on icon markers.

### How the Script Parses Source Files

The parser preserves the first 20 lines of any source file—this includes the header and table of contents—then processes remaining lines to find category markers. According to the source code in [`index.js`](https://github.com/Axorax/awesome-free-apps/blob/main/index.js) (lines 7‑27), the script uses a `Set` of emoji icons to identify which platform or attribute an app belongs to:

```javascript
const emojis = new Set(["🪟","🍎","🐧","🟢","⭐","🤖"]);
…
if ([…emojis].some(e=> line.includes(e)) && !line.includes(emoji)) continue;

```

Lines that contain emojis not matching the target category are skipped, ensuring only relevant entries survive the filter.

### The create() Helper Function

The `create` function (lines 4‑33 in [`index.js`](https://github.com/Axorax/awesome-free-apps/blob/main/index.js)) handles the actual file generation. Its signature accepts the source file, output filename, and target emoji:

```javascript
function create(file, fileName, emoji) { … }

```

This function streams the input file, applies the emoji-based filter, rewrites relative links so they resolve correctly from the new location, and writes the result to `./filter/<fileName>.md` using `fs.writeFileSync` (line 31).

### Emoji-Based Filtering Logic

The script recognizes six distinct markers that map to specific filter outputs:

- **🪟** – Windows-only applications
- **🍎** – macOS-only applications  
- **🐧** – Linux-only applications
- **🟢** – Open-source applications
- **⭐** – Recommended applications
- **🤖** – Android applications

When generating [`open-source-only.md`](https://github.com/Axorax/awesome-free-apps/blob/main/open-source-only.md), the script keeps only lines containing the 🟢 emoji (plus the shared header), discarding proprietary software entries.

## Running the Generator Locally

Contributors can regenerate all filter files on-demand using the command line. This is useful when updating master lists locally before submitting a pull request.

Execute the categorization command from the repository root:

```bash
node index.js --categorize

```

The script outputs timing metrics for each generated file:

```

windows-only time: 12ms
macOS-only time: 9ms
open-source-only time: 11ms

```

After execution, the `filter/` directory contains updated markdown files like [`filter/open-source-only.md`](https://github.com/Axorax/awesome-free-apps/blob/main/filter/open-source-only.md) and [`filter/windows-only.md`](https://github.com/Axorax/awesome-free-apps/blob/main/filter/windows-only.md), reflecting the current state of [`README.md`](https://github.com/Axorax/awesome-free-apps/blob/main/README.md) and [`MOBILE.md`](https://github.com/Axorax/awesome-free-apps/blob/main/MOBILE.md).

## Automated Maintenance with GitHub Actions

The repository uses continuous integration to ensure filter files never drift out of sync with the master lists. The workflow file [`.github/workflows/renew-categories.yml`](https://github.com/Axorax/awesome-free-apps/blob/main/.github/workflows/renew-categories.yml) defines a GitHub Actions job that runs the generator automatically.

The workflow performs these steps:

1. Checks out the repository
2. Sets up Node.js 22
3. Executes `node index.js --categorize`
4. Commits and pushes any changes back to the repository

The workflow triggers on `workflow_dispatch` (manual run) or can be scheduled via cron, ensuring the filter files stay synchronized without manual editing. Because the generation is deterministic, the CI pipeline produces identical outputs to local runs.

## Summary

- **Filter files** ([`open-source-only.md`](https://github.com/Axorax/awesome-free-apps/blob/main/open-source-only.md), [`windows-only.md`](https://github.com/Axorax/awesome-free-apps/blob/main/windows-only.md), etc.) are deterministic outputs generated from [`README.md`](https://github.com/Axorax/awesome-free-apps/blob/main/README.md) and [`MOBILE.md`](https://github.com/Axorax/awesome-free-apps/blob/main/MOBILE.md).
- The **Node.js script** at [`index.js`](https://github.com/Axorax/awesome-free-apps/blob/main/index.js) uses emoji markers (🪟, 🍎, 🐧, 🟢, ⭐, 🤖) to categorize entries line-by-line.
- The **`create()`** function handles parsing, link rewriting, and writing to the `filter/` directory.
- **Local generation** requires running `node index.js --categorize`.
- **GitHub Actions** automates regeneration via [`.github/workflows/renew-categories.yml`](https://github.com/Axorax/awesome-free-apps/blob/main/.github/workflows/renew-categories.yml), committing changes automatically.

## Frequently Asked Questions

### What are the filter files in awesome-free-apps?

The filter files are pre-sliced versions of the main application lists located in the `filter/` directory. They contain subsets of [`README.md`](https://github.com/Axorax/awesome-free-apps/blob/main/README.md) and [`MOBILE.md`](https://github.com/Axorax/awesome-free-apps/blob/main/MOBILE.md) filtered by platform (Windows, macOS, Linux, Android) or attributes (open-source only, recommended). These files allow users to view platform-specific lists without manually searching through the comprehensive master documents.

### How do I update the filter files manually?

Run `node index.js --categorize` from the repository root after modifying [`README.md`](https://github.com/Axorax/awesome-free-apps/blob/main/README.md) or [`MOBILE.md`](https://github.com/Axorax/awesome-free-apps/blob/main/MOBILE.md). This command regenerates all files in the `filter/` directory based on the current content of the master lists. You should not edit files in the `filter/` directory directly, as the CI workflow will overwrite manual changes on the next automated run.

### Which emoji markers trigger filter generation?

The script recognizes six emoji markers defined in the `emojis` Set at line 7 of [`index.js`](https://github.com/Axorax/awesome-free-apps/blob/main/index.js): 🪟 (Windows), 🍎 (macOS), 🐧 (Linux), 🟢 (Open-source), ⭐ (Recommended), and 🤖 (Android). Each marker corresponds to a specific output file; for example, entries tagged with 🟢 appear in [`filter/open-source-only.md`](https://github.com/Axorax/awesome-free-apps/blob/main/filter/open-source-only.md), while 🪟 entries populate [`filter/windows-only.md`](https://github.com/Axorax/awesome-free-apps/blob/main/filter/windows-only.md).

### How does the GitHub Actions workflow keep filter files synchronized?

The workflow defined in [`.github/workflows/renew-categories.yml`](https://github.com/Axorax/awesome-free-apps/blob/main/.github/workflows/renew-categories.yml) automatically executes `node index.js --categorize` whenever triggered manually or on a schedule. If the script modifies any filter files, the workflow commits those changes back to the repository. This ensures the filter files remain exact mirrors of the categorized content in [`README.md`](https://github.com/Axorax/awesome-free-apps/blob/main/README.md) and [`MOBILE.md`](https://github.com/Axorax/awesome-free-apps/blob/main/MOBILE.md) without requiring human intervention.