Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion packages/helloworld/android/app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,12 @@ android {
keyPassword = "release-key-password"
}
}

val devServerHost = project.findProperty("DEV_SERVER_HOST") as String? ?: "10.0.2.2"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we also do DEV_SERVER_PORT?

buildTypes {
debug {
isDebuggable = true
applicationIdSuffix = ".debug"
buildConfigField("String", "DEV_SERVER_HOST", "\"$devServerHost\"")
}
release {
isMinifyEnabled = true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ class MainActivity : Activity() {

var uri = ""
uri = if (BuildConfig.DEBUG == true) {
"http://10.0.2.2:3000/main.lynx.bundle?fullscreen=true"
val devServerHost = BuildConfig.DEV_SERVER_HOST
"http://$devServerHost:3000/main.lynx.bundle?fullscreen=true"
} else {
"main.lynx.bundle"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import com.facebook.imagepipeline.core.ImagePipelineConfig
import com.facebook.imagepipeline.memory.PoolConfig
import com.facebook.imagepipeline.memory.PoolFactory
import com.lynx.devtoolwrapper.LynxDevtoolGlobalHelper
import com.lynx.service.devtool.LynxDevToolService
import com.lynx.service.image.LynxImageService
import com.lynx.service.log.LynxLogService
import com.lynx.tasm.LynxEnv
Expand All @@ -31,6 +32,8 @@ class MainApplication : Application() {
LynxServiceCenter.inst().registerService(LynxImageService.getInstance())
LynxServiceCenter.inst().registerService(LynxLogService)
LynxServiceCenter.inst().registerService(LynxHttpService)
LynxServiceCenter.inst().registerService(LynxDevToolService.INSTANCE)

}

private fun initLynxEnv() {
Expand Down
6 changes: 5 additions & 1 deletion packages/helloworld/apple/HelloWorld/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@ class AppDelegate: UIResponder, UIApplicationDelegate {

// Register new modules with:
// config.register(YourModuleName.self)

lynxEnv.lynxDebugEnabled = true
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's to it only for dev

#if DEBUG
    // Your debug-only code here
#endif

// Enable Lynx DevTool
lynxEnv.devtoolEnabled = true
// Enable Lynx LogBox
lynxEnv.logBoxEnabled = true
lynxEnv.prepareConfig(config)

return true
Expand Down
4 changes: 3 additions & 1 deletion packages/helloworld/apple/HelloWorld/SceneDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,10 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
rootViewController.view = lynxView

#if DEBUG
// Get dev server host from environment variable or use localhost as fallback
let devServerHost = ProcessInfo.processInfo.environment["DEV_SERVER_HOST"] ?? "localhost"
lynxView.loadTemplate(
fromURL: "http://localhost:3000/main.lynx.bundle?fullscreen=true",
fromURL: "http://\(devServerHost):3000/main.lynx.bundle?fullscreen=true",
initData: nil
)
#else
Expand Down
80 changes: 41 additions & 39 deletions packages/helloworld/package.json
Original file line number Diff line number Diff line change
@@ -1,40 +1,42 @@
{
Copy link
Collaborator

@szymonrybczak szymonrybczak Oct 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why this change? is it compatible with the current linter config? btw we should add lint and type checks to the CI pipeline

"name": "HelloWorld",
"version": "1.0.0",
"type": "module",
"scripts": {
"build": "rspeedy build",
"dev": "rspeedy dev",
"format": "prettier --write .",
"lint": "eslint .",
"preview": "rspeedy preview",
"test": "vitest run"
},
"dependencies": {
"@lynx-js/react": "^0.112.5"
},
"devDependencies": {
"@eslint/js": "^9.32.0",
"@lynx-js/preact-devtools": "^5.0.1-6664329",
"@lynx-js/qrcode-rsbuild-plugin": "^0.4.1",
"@lynx-js/react-rsbuild-plugin": "^0.10.13",
"@lynx-js/rspeedy": "^0.11.0",
"@lynx-js/types": "3.4.11",
"@rsbuild/plugin-type-check": "1.2.4",
"@testing-library/jest-dom": "^6.8.0",
"@types/react": "^18.3.23",
"eslint": "^9.32.0",
"eslint-plugin-react-hooks": "^5.2.0",
"eslint-plugin-react-refresh": "^0.4.20",
"globals": "^16.3.0",
"jsdom": "^26.1.0",
"prettier": "^3.6.2",
"typescript": "~5.9.2",
"typescript-eslint": "^8.38.0",
"vitest": "^3.2.4"
},
"engines": {
"node": ">=18"
},
"private": true
}
"name": "HelloWorld",
"version": "1.0.0",
"type": "module",
"scripts": {
"build": "rspeedy build",
"dev": "rspeedy dev",
"format": "prettier --write .",
"lint": "eslint .",
"preview": "rspeedy preview",
"test": "vitest run",
"install:android": "./scripts/android.sh",
"install:ios": "./scripts/ios.sh"
},
"dependencies": {
"@lynx-js/react": "^0.112.5"
},
"devDependencies": {
"@eslint/js": "^9.32.0",
"@lynx-js/preact-devtools": "^5.0.1-6664329",
"@lynx-js/qrcode-rsbuild-plugin": "^0.4.1",
"@lynx-js/react-rsbuild-plugin": "^0.10.13",
"@lynx-js/rspeedy": "^0.11.0",
"@lynx-js/types": "3.4.11",
"@rsbuild/plugin-type-check": "1.2.4",
"@testing-library/jest-dom": "^6.8.0",
"@types/react": "^18.3.23",
"eslint": "^9.32.0",
"eslint-plugin-react-hooks": "^5.2.0",
"eslint-plugin-react-refresh": "^0.4.20",
"globals": "^16.3.0",
"jsdom": "^26.1.0",
"prettier": "^3.6.2",
"typescript": "~5.9.2",
"typescript-eslint": "^8.38.0",
"vitest": "^3.2.4"
},
"engines": {
"node": ">=18"
},
"private": true
}
87 changes: 87 additions & 0 deletions packages/helloworld/scripts/android.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
#!/bin/bash
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure if we should land it, we can but this will super temporary and tbh I would just properly implement run:android and run:ios commands


# android.sh - Build Android app with automatic dev server IP detection

set -e

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

echo -e "${GREEN}🔍 Detecting development server IP address...${NC}"

# Function to detect IP on different platforms
detect_ip() {
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
# Linux
ip -4 addr show $(ip route show default | awk '{print $5}' | head -n1) 2>/dev/null | grep -oP '(?<=inet\s)\d+(\.\d+){3}' | head -n1
elif [[ "$OSTYPE" == "darwin"* ]]; then
# macOS
route get default | grep interface | awk '{print $2}' | xargs ifconfig | grep -E "inet [0-9]" | grep -v 127.0.0.1 | awk '{print $2}' | head -n1
elif [[ "$OSTYPE" == "msys" ]] || [[ "$OSTYPE" == "win32" ]]; then
# Windows (Git Bash/MSYS2)
ipconfig | grep -A 5 "Wireless LAN adapter Wi-Fi\|Ethernet adapter" | grep "IPv4 Address" | head -n1 | sed 's/.*: //'
else
echo -e "${YELLOW}⚠️ Unknown OS type: $OSTYPE${NC}"
echo -e "${YELLOW}Please manually specify your IP address${NC}"
return 1
fi
}

# Try to detect the IP
DEV_SERVER_IP=$(detect_ip)

if [ -z "$DEV_SERVER_IP" ]; then
echo -e "${YELLOW}⚠️ Could not automatically detect IP address${NC}"
echo -e "${YELLOW}Please enter your development machine's IP address:${NC}"
read -p "IP Address: " DEV_SERVER_IP

if [ -z "$DEV_SERVER_IP" ]; then
echo -e "${RED}❌ No IP address provided. Using automatic detection in app.${NC}"
DEV_SERVER_IP=""
fi
fi

if [ -n "$DEV_SERVER_IP" ]; then
echo -e "${GREEN}✅ Using development server IP: $DEV_SERVER_IP${NC}"
else
echo -e "${YELLOW}⚠️ Will use automatic detection in the app${NC}"
fi

# Change to Android project directory
cd "android"

echo -e "${GREEN}🔨 Building Android app...${NC}"

# Build the debug APK with the detected IP
if [ -n "$DEV_SERVER_IP" ]; then
./gradlew assembleDebug -PDEV_SERVER_HOST="$DEV_SERVER_IP"
else
./gradlew assembleDebug
fi

echo -e "${GREEN}✅ Build complete!${NC}"
echo -e "${GREEN}📱 APK location: android/app/build/outputs/apk/debug/app-debug.apk${NC}"

# Optionally install the APK if device is connected
if command -v adb &> /dev/null; then
if adb devices | grep -q "device$"; then
echo -e "${YELLOW}📱 Android device detected. Install APK? (y/n):${NC}"
read -p "" install_choice
if [[ $install_choice == "y" || $install_choice == "Y" ]]; then
echo -e "${GREEN}📲 Installing APK...${NC}"
adb install -r app/build/outputs/apk/debug/app-debug.apk
echo -e "${GREEN}✅ APK installed successfully!${NC}"
fi
else
echo -e "${YELLOW}📱 No Android device connected via ADB${NC}"
fi
fi

if [ -n "$DEV_SERVER_IP" ]; then
echo -e "${GREEN}🚀 Start your development server with:${NC}"
echo -e "${GREEN} cd project && npm run dev${NC}"
echo -e "${GREEN}🌐 Server should be accessible at: http://$DEV_SERVER_IP:3000${NC}"
fi
124 changes: 124 additions & 0 deletions packages/helloworld/scripts/ios.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
#!/bin/bash

# ios.sh - Build iOS app with automatic dev server IP detection

set -e

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

echo -e "${GREEN}🔍 Detecting development server IP address...${NC}"

# Function to detect IP on macOS (only platform needed for iOS development)
detect_ip() {
# macOS
route get default | grep interface | awk '{print $2}' | xargs ifconfig | grep -E "inet [0-9]" | grep -v 127.0.0.1 | awk '{print $2}' | head -n1
}

# Try to detect the IP
DEV_SERVER_IP=$(detect_ip)

if [ -z "$DEV_SERVER_IP" ]; then
echo -e "${YELLOW}⚠️ Could not automatically detect IP address${NC}"
echo -e "${YELLOW}Please enter your development server IP address:${NC}"
read -p "IP Address: " DEV_SERVER_IP

if [ -z "$DEV_SERVER_IP" ]; then
echo -e "${RED}❌ No IP address provided. Using localhost fallback.${NC}"
DEV_SERVER_IP="localhost"
fi
fi

if [ -n "$DEV_SERVER_IP" ]; then
echo -e "${GREEN}✅ Using development server IP: $DEV_SERVER_IP${NC}"
else
echo -e "${YELLOW}⚠️ Will use localhost fallback${NC}"
DEV_SERVER_IP="localhost"
fi

# Try to detect the IP
DEV_SERVER_IP=$(detect_ip)

if [ -z "$DEV_SERVER_IP" ]; then
echo -e "${YELLOW}⚠️ Could not automatically detect IP address${NC}"
echo -e "${YELLOW}Please enter your development machine's IP address:${NC}"
read -p "IP Address: " DEV_SERVER_IP

if [ -z "$DEV_SERVER_IP" ]; then
echo -e "${RED}❌ No IP address provided. Using localhost fallback.${NC}"
DEV_SERVER_IP="localhost"
fi
fi

if [ -n "$DEV_SERVER_IP" ]; then
echo -e "${GREEN}✅ Using development server IP: $DEV_SERVER_IP${NC}"
else
echo -e "${YELLOW}⚠️ Will use localhost fallback${NC}"
DEV_SERVER_IP="localhost"
fi

# Check if we're on macOS (required for iOS development)
if [[ "$OSTYPE" != "darwin"* ]]; then
echo -e "${RED}❌ iOS development requires macOS and Xcode${NC}"
echo -e "${YELLOW}📱 Please run this script on a macOS machine with Xcode installed${NC}"
echo -e "${YELLOW}💡 For now, the iOS app has been configured to use: $DEV_SERVER_IP${NC}"
echo -e "${YELLOW}🔧 You'll need to manually open the Xcode project to build: apple/HelloWorld.xcodeproj${NC}"
exit 1
fi

# Change to iOS project directory
cd "apple"

echo -e "${GREEN}🔨 Building iOS app...${NC}"

# Build the iOS app with the detected IP
if [ -n "$DEV_SERVER_IP" ]; then
# Set environment variable for the build
export DEV_SERVER_HOST="$DEV_SERVER_IP"

# Build for iOS simulator (development)
xcodebuild -project HelloWorld.xcodeproj -scheme HelloWorld -destination 'platform=iOS Simulator,name=iPhone 15' clean build

echo -e "${GREEN}✅ Build complete!${NC}"
echo -e "${GREEN}📱 App built for iOS simulator${NC}"
else
echo -e "${RED}❌ Build failed${NC}"
exit 1
fi

# Optionally open iOS simulator and install app if available
if command -v xcrun &> /dev/null; then
echo -e "${YELLOW}📱 Opening iOS Simulator...${NC}"
# Open the default iOS simulator
xcrun simctl boot "iPhone 15" &> /dev/null || true

# Find the most recently built app in derived data
# The template system will have replaced "HelloWorld" with the actual project name
APP_PATH=$(find ~/Library/Developer/Xcode/DerivedData -name "*.app" -type d -path "*/Build/Products/*" 2>/dev/null | head -n1)

if [ -n "$APP_PATH" ]; then
echo -e "${YELLOW}📲 Installing app on simulator...${NC}"
# Install the app on the simulator
xcrun simctl install "iPhone 15" "$APP_PATH"
echo -e "${GREEN}✅ App installed successfully on simulator!${NC}"

echo -e "${YELLOW}🚀 Launching app...${NC}"
# Launch the app (bundle ID will be whatever the template system generated)
xcrun simctl launch "iPhone 15" "$(basename "$APP_PATH" .app)"
else
echo -e "${YELLOW}⚠️ App not found in derived data${NC}"
echo -e "${YELLOW}💡 You can manually launch the app from Xcode${NC}"
echo -e "${YELLOW}🔧 Look for your app in Xcode's Products folder${NC}"
fi
else
echo -e "${YELLOW}📱 xcrun not found. Simulator management skipped${NC}"
fi

if [ -n "$DEV_SERVER_IP" ]; then
echo -e "${GREEN}🚀 Start your development server with:${NC}"
echo -e "${GREEN} cd project && npm run dev${NC}"
echo -e "${GREEN}🌐 Server should be accessible at: http://$DEV_SERVER_IP:3000${NC}"
fi