Node.js Entry Point (REQUIRED)
Azure Functions Node.js v4 programming model requires an entry point file that initializes the runtime.
⛔ CRITICAL: Without this file, functions will deploy but return 404 on all endpoints.
Project Structure (CRITICAL)
The project structure MUST be:
project-root/ # ← azure.yaml project: "."
├── azure.yaml
├── package.json # ← MUST be at ROOT, not in src/
├── host.json
├── src/
│ ├── index.js # ← Entry point (app.setup)
│ └── functions/
│ ├── myFunction.js # ← Functions auto-discovered
│ └── ...
└── infra/⛔ CRITICAL:
package.jsonMUST be at project root, NOT insidesrc/. Theazure.yamlmust haveproject: .(notproject: ./src/).
JavaScript: src/index.js
This file MUST exist and MUST NOT be removed when replacing trigger files.
const { app } = require('@azure/functions');
app.setup({
enableHttpStream: true,
});TypeScript: src/index.ts
This file MUST exist and MUST NOT be removed when replacing trigger files.
import { app } from '@azure/functions';
app.setup({
enableHttpStream: true,
});package.json Configuration
The package.json MUST be at the project root (same level as azure.yaml).
⛔ CRITICAL: The glob pattern is REQUIRED for function discovery! Using
"main": "src/index.js"alone will result in 404 on all endpoints. You MUST use the glob pattern that includes function files.
JavaScript (REQUIRED pattern)
{
"main": "src/{index.js,functions/*.js}",
"scripts": {
"start": "func start"
}
}TypeScript (REQUIRED pattern)
{
"main": "dist/src/{index.js,functions/*.js}",
"scripts": {
"build": "tsc",
"prestart": "npm run build",
"start": "func start"
}
}Why the Glob Pattern is Required: The Azure Functions Node.js v4 runtime uses the
mainfield to determine which files to load. Unlike CommonJS whererequire()chains work, the runtime needs ALL function files explicitly listed in the glob pattern. Without the glob, onlyindex.jsloads and functions insrc/functions/are never registered.
>
❌ WRONG:
"main": "src/index.js"— Functions not discovered, 404 on all routes ✅ CORRECT:"main": "src/{index.js,functions/*.js}"— All functions discovered
azure.yaml Configuration
services:
api:
project: . # ← ROOT directory, not ./src/
language: js # or ts for TypeScript
host: function⛔ CRITICAL: Use
project: .— NOTproject: ./src/. The runtime expectspackage.jsonat the project root.
Build Requirements (TypeScript only)
Before deployment, TypeScript must be compiled:
npm run buildThis outputs JavaScript to dist/ which is what Azure Functions actually runs.
Common Mistakes
| Mistake | Symptom | Fix |
|---|---|---|
Using "main": "src/index.js" without glob | 404 on all endpoints | Use "main": "src/{index.js,functions/*.js}" |
Missing src/index.js | 404 on all endpoints | Add the entry point file with app.setup() |
Deleting src/index.js when replacing triggers | 404 after recipe applied | Keep index.js, only replace function files |
package.json in src/ instead of root | 404, functions not found | Move package.json to project root |
project: ./src/ in azure.yaml | Deployment fails or 404 | Use project: . |
Missing npm run build for TypeScript | 404 or old code runs | Run build before deploy |
⛔ #1 CAUSE OF 404 ERRORS: Using
"main": "src/index.js"instead of the glob pattern. The globsrc/{index.js,functions/*.js}is REQUIRED — it's not optional!
Terraform vs Bicep: Source Code is IDENTICAL
The Node.js source code and package.json are exactly the same for both IaC types.
Only the infra/ folder differs:
- Bicep:
infra/*.bicep - Terraform:
infra/*.tf
⚠️ If you find yourself changing imports or source code because of IaC choice, something is wrong. The application code should be IaC-agnostic.