้ขใค็ซดๆฟ?Qin ๆต ๏ฝ็้ปๅฟๅ ชๆดๆๆค้ๅฒ๎ AI ้ๆฌๅฌ้ฎไพ็ด็?Qin ็็ป็ๆฉๆฏ๎้ไฝน็ฏๅฏคๅๆฐ้ฎใง่ฎฒ้?
![]()
Qin ้จๅญๆดฐ้ๅฆ็ฌ้๎ๅ้ๆฐซ็ซดๆถ๎โฌๆปๆดฟ้้ขๅฌ้จ?Java ้ๅซ็ผๅฎธใฅๅฟ้ฅๆฟ็ด้ฐๅฑพๆงธ้ๆฐซ็ซด้?AI-native ้ใฆ็คๆดๆๆค็๎ กโ้?
- ๆตฃ่ทจๆค ESM ๆคๅบข็ธ็๎ ็กถ
- ๆต ?JVM ๆตฃๆป่ดๆถๆ๎ฆ้ๅบฃ๎ฌ/ๆฉๆฏ๎้่ทบๅด้?- ๆต ใฅๅข ็ป?JS ้ข็ธๅๆถ่น๎ๆถโฌ็ปซ่คๆดฐ้?- ้ขใง็ฒบๆถโฌ้จๅฎ๎ข็ทโฌๅฆฏโณ็ท็ๅๆดๆดๆๆค้ไพใ้๎ฌโฌไฝนๅธด้๏ฝโฌไฝนๆ้น๎ป็ฌ้ฎใง่ฎฒ
็ตๅญๆค้ด้ฃๆฎ้ๅๅ ๆตฃๆป็้๎ค็ดฐ
- ้ข?Qin ้ปๅฟๅ ชๆดๆๆค
- ้ข?AI ้ข็ธๅ้ดๆ ฆๆ จ้?Qin ๆต ๏ฝ็
qin dev้๎ๆนด้๎ๅงฉqin deployๆถโฌ้ฟ๎ๅด็ผ? ้ขใฆๅๆถๅถๆธถ็ไฝธๅ้ๅฒ็ธพ้?- ้ๅถ๎ฌๆฉๆจปๆงธ้ๅบฃ๎ฌ
- controller / service / DTO ้ฌๅบ็ฎ้ท?- Spring / JS / ้ฎใง่ฎฒ็ผๅๅฆญ้ฌๅบ็ฎ้บ? ๆฉๆฌ็ฐบๆดๆ๎้ซๆญ๎้ข?Qin ็ผๆ ฌ็ง้ฃใฃโฌไฝฝ็น็ๅฑพๆค้ไฝธไผ้็ฝๆผ้ๅฑฝ้ฉ้็ๆฝต็ไฝฝ๎้?
่คฐๆณๅข Qin ๆฉๆจบ๎ฉ้ฆใขโฌๆป็ฒ ็๎ กโ/ๆฉๆฏ๎้่ทบ็็บญโฌ็็ฌๆฆ็งๆฟๆๆตัๆง่คฐใกโฌไฝฒโฌๆฟๆฎ้่ต๎้?
-
้ๆฟๆนชๅฎธ่ฌ็ฒก้ๅค็ฒบๆถโฌ็๎ กโๅฆฏโณ็ท้ไธฃVM/JS backend้ไนฃ.qin + Spring Boot` demo้ไนผarget zoning
-
ๆตฃๅๆธถ็ผๅ ่ฐ้ฌไฝท็ฌๆดๆ๎็โๆซ้ซๆฐฑๆค้ด็ฝๆฑ้็ทไป ้ฃๆฌๆนช้ฅๆปๅข้ๆฌๅข ้ๅบฃ๎ฌ้ๅ็ฐ + ็นๅคธๅฏๆพนๆฅโฌๆฟๆฎๅฎธใค็ถ้็ฐ็ดก้ฒ? ่คฐๆณๅข ้ตั๎ๆตผๆจบๅ็ปพั็ดฐ
-
้ๅ ๅฆธ Qin ้ๆฐญๅๆถโฌ้ใฆๆซ้ซๆฐฌๅฝฒ้ขใงๆฎ้ใฆ็ค็๎ กโ
-
้ๅ ็ฌ้ด?Stage 1 ้จๅฎ๎ข็ทโฌ้ไฝบ็ดช็ๆโฌไฝฝ็น็ๅฑปโฌไฝธๅ้ๅ ฅๆผ็บ๎ว็นๆฐญโฌ?- ้ๆฎ็ฎ็ๅๆฎ Qin ๆดๆๆค้ถๅ่้ฃๆฌๅ Stage 2 ้ๅถ้ด็ผ็ธๅธนๆฉ? ้ๆ็ฌ้ๅฏธๆฎๆตัๆง็นๆฐซ็ถ ็ไพ็ดฐ
-
packages/qin-runtime-core/QIN_APP_MODEL.md -
packages/qin-runtime-core/QIN_MISSION_AND_VALUE.md -
packages/qin-runtime-core/QIN_PRODUCT_POSITIONING.md -
packages/qin-runtime-core/QIN_LANGUAGE_TARGET_MODEL.md -
packages/qin-runtime-core/QIN_JS_COMPATIBILITY_MODEL.md -
packages/qin-runtime-core/QIN_CURRENT_SUPPORT_MATRIX.md -
packages/qin-runtime-core/QIN_NPM_COMPATIBILITY_POLICY.md -
packages/qin-runtime-core/QIN_HOST_CAPABILITY_MODEL.md -
packages/qin-runtime-core/QIN_JS_ON_JVM_FEASIBILITY.md -
packages/qin-runtime-core/QIN_CSSTS_INTEGRATION_MODEL.md
้ปๅฟๅ ชๆดๆๆค้ๅฒโฌๅฑผ็ฌ้๎ๅ้ปๅฟๅ ช้ๅถ๎ฌ/้ๅบฃ๎ฌ้ๅ็ฐ
Qin ้จๅฌๅฐๆถๅค็ฌ้ฆใค็ฐฌ้ฅๆปๅฆธ JavaScript ้ข?Java ้ฒๅถ ๅๆถโฌ้ฌๅถโฌๆฟโฌ? ๆฟกๅ็ Qin ้โฌ็ผๅ ๅฝง้๎ค็ดฐ
- ้บใจ็น JS ้จๅฎ๎ขๅจ?- ้ๅถ ๅงๆถๅฉ ๅ ็ๅชๆค Spring Boot / JVM ้ข็ธโฌ? ้ญ๏ฝ ็ ้จๅช็ฏ้ๅ ผๆงธๆถๅถ ๎ๆพถั ๆฎ้? Qin ้ช็ธ๎็ไฝฝ็้ๅบฃๆฎๆต ๅณฐโฌๅ ผๆงธ้?
- ้ข?AI ้ๅฏธๅ้ฎๅคๆฎ้้ขๅฌ็๎
็กถ้ๅฒ็ฒบๆถโฌ้ๆ๎ฟ้ๅถ
ๆ็ป๎็ด้ๆไผๆตฃ?- ้ฉๅญๅธดๆฉๆถๅ JVM /
.class/ Spring Boot / Java ้ข็ธโฌ?- ้ๅถ็ถๆพถๆฐณ๎ข็ทโฌ้ไฝธ๎ฟๆฉๆฏ๎้่บฒโฌไฝธ๎ฟ้ๅซ็ผ้พๆ็พๆถๅฌฎๆฃฟ้จๅฎๅ ๅงๆ๎ฒ้ๅๅฎณ - ้โฌ็ผๅ ๅฆธ
dev/build/deploy้่ตๅ้็ฟ ็ซดๆตฃๆณๅฏฒ้จๅซๅ้ๅ ็ถๆฅ ? ๆถ็ทๆฐจ้๎๎ฉ้ๅญฎin ๆถๅถๆงธๆถ่ฝฐ็ฐก้ฅๆปๅ JS้ฅๆฟโฌๅฑฝ็จ้ฆใฃโฌ?Qin ้๎ ๆน้ฆใฅ็ ้ณ่็ซ้ใฆๆดฟๅฏฎ่นๆฎ JVM-centered fullstack workflow ้่ฎน็ด้ตๅถ โฌ็ ็ทฑๆตฃๆป่ดๆถโฌ้ใงๅซญ็ปๅฌญ๎ข็ทโฌ็ผั ็ป้ๆ็้?
-
*ๆดๆๆคๅฏฎโฌ้ๆ็ฒ้ๆฐ็นๆด๏นๅ็?
- ้ขใฆๅ้ๅ ฃ๎ฆๆฉ๎ฃโฌๆฟโฌๅจๅข ็ป๎โฌไฝธๆ็ป๎โฌไธTO้ไฝฝ็พ้ขไพฟโฌไพๅด็ผ? - Qin ้จๅญๆดฐ้ๅจๆงธ้ๅ ๅผฟๆฉๆฟ็ฐฒ้ขใฆๅฐ้ฅๆ ็ด้ๅถๆฑ้ชๅฒๅฝด็ๆ็ด target ็ผๅๅฆญ
-
*AI ้ๆฌ็ฐฒ้ขใคๅฌ้ฎไฝนๆคๆถๅฉ็ฌ ้ๅงใ็บฐ?
- ๆตผ็ต็ฒบๅฎธใงโผ้โฌ็ไฝฝๆณๆพถๆฐซ้ๅฆๅ็ฆ็ๅๅขๅฎธใฅ๎ฎๆฆป? - Qin ้โฌ็ไฝนๅฝๆธๆถๆดฟ็ผ็ถ็ซด้ไฝท็ถๅงั็ฎ้ไฝธๅฝฒ้ข็ธๅ้จๅซ็ฐฒ้ขใฆฤ้จ?
-
*้ใฆ็คๅฏฎโฌ้ๆ ๆฎๆฉๆฏ๎ๆถๅบจๅด็ผๆฅๆผ็บ๎็น้ฒ?
- ้๎ๆนดๆฉๆฏ๎้ไฝท็ทท็งๆ จๅซพ็ๅซโฌไฝธ๎ๆถๅฉๆณฆ้ดๆฉโฌไฝธๅฝ็ฏๅง็ฌ็ปพๅๅ ้ๅๆ
- Qin ้ฉ๎ฝ็ฃ้๎็ฒบๆถโฌๆถ?
dev/build/deploy
-
ๆดๆ็ฐ้ชๅฒๅฝดๅฎธ๎ผ็ด้ๆฎๆนถๆฉๅจๆฃญ
- JVM้ไธฃS้ไธผpring้ไฝน็ฅป็ๅ ๆซ้ณ่ๅง้๎็ฐฒ้๎้ฉ้ๆฟ็ๅฏฎโฌ้๎๎ฝ
- Qin ้ฉ๎ฝ็ฃ้๎๎ฎ้ ๎โฌๆฐฌ็ฐฒ้ขใค็ถ้ฐๅญๆ้ฒๅฟๆฎฃ้ๅฟ็นๆตๆถ็้ๆฎ็ฒ้บ?
Qin ๆธๆฟๅง้ๅญๆๅฏฐๅ ๅทฑ้จๅซไผ็ปๅฌชไผ้็ฝๆผ้ณ่ๅง้?
- JSON / TypeScript ๆคๅบข็ธ้ฐๅถ็
- ้๎ๆนดๆธๆฟ็ฆๆถ?monorepo ้๎ๅฏ
- Java 25 / JVM ๅฎธใฅๅฟๆตฃๆถ้ด้ๅๅ
qin run / sync / build
ๆตฃๅ็นๆตๆถ็ๆต?Qin ๆตัๆง้จๅช็ซด้ฎใฅๅ้ๅฑผ็ฌ้ๅถๆงธ Qin ้จๅฌๆธถๆฅๆจบ็ฐ็นๆฐซ็ฎ้?
Maven pom.xml (30+ ็?:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>my-app</artifactId>
<version>1.0.0</version>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>4.0.6</version>
</dependency>
</dependencies>
<repositories>
<repository>
<id>central</id>
<url>https://repo1.maven.org/maven2</url>
</repository>
</repositories>
</project>Qin qin.config.js (10 ็?:
{
"name": "my-app",
"version": "1.0.0",
"dependencies": {
"org.springframework.boot:spring-boot-starter-web": "4.0.6"
}
}- ้?*้ๅถ๎ฌๆ?Java ๅฏฎโฌ้ๆฃโฌ? - ้็ธๅ้จ?npm ๆคๅบข็ธ้ฐๅถ็
- ้?*้ๅฑฝโฌ?XML ้จ?Java ๅฏฎโฌ้ๆฃโฌ? - ็ป โฌๅจฒไฝบๆฎ JSON/TypeScript ้ฐๅถ็
- ้?Monorepo ้ขใฆๅ - ้็บๆๆพถๆฐถใ้ฉ๎ฝๆฎ้ธ?
- ้?*ๆฉ่ฅ็ฐ้ฌัๅ ้จๅซ็ด้ๆฃโฌ? - Java 25 ็ฏ๏ธฝๆฝต 2-5x ้ฌัๅ ้ปๆฌๅด
- ้?*้ใฆ็คๅฏฎโฌ้ๆฃโฌ? - ้ๅฏ็ Qin ้็บๆ้ๅถ๎ฌๅฏฎโฌ้ๆๆน้โณๆซ้ๅฑผ็ฌๆธๆฟ็ฆ Vite ็ๆฏ็น็ป?
Qin ้จๅฌ็ณ่นๅจ็พๆตฃๅถ็ดฐ
- *Qin = JS/ESM ็๎ ็กถๆคๅบข็ธ้จๅญ็ดช็ๆ็ท็๎ กโ้ๅVM ้ๅฎ็ณ้?
- ๆถๅถๆงธ็นๅฑพๆฃ JS ๅฏฎๆๆธ้ๅฑผ็ฌ้็ ๎ Node ๆถๆดๆน API
- ้ฉ๎ฝ็ฃ้๎โฌๆป็ซดๆฟๆฅ๎ข็ทโฌ้ๆฌๅข ้ๅบฃ๎ฌ้ฅๆฟ็ด้ฐๅฑผ็ฌ้๎โฌๆป๎ฒ้?Node ้ข็ธโฌไฝฒโฌ?
ๆถ่ฝฐ็ฒๆถๅ ฃ๎ฆ้ฆ?Java ๆธั็้?JS-SDK้ๅ ๎ง console / Math / JSON้ๅค็ดฐ
- Qin ้ๅบฃ๎ฌ้ฉ๎ฝ็ฃ้?
.class้ๅฒ็น็ๅฑฝๆนช JVM้ๅฑผ็ฌ้๎ๆดฟ้บใจ็ช้ฆใฆ็ฅป็ๅ ๆซ้ฒ? - ๆตฃๅ๎ข็ทโฌ็ๅๅฐ้ข?JS/ESM ็๎ ็กถ้ๅฑฝ็ด้ๆฃโฌๅญใ้ๆต็ดฐๆตฃ่ทจๆค JS ้ๅญ็ผ้ณ่ๅง
- ๆฟกๅ็ๅจโๆน JS-SDK้ๅฒ๎ขๅจๆกๆซง้่ทบๅ JS้ๅฒ็น็ๅฑพๆค็ๅฑผ่ด็ๅ็ดฐ้๎ ็ฐ
- ้ฅ็ณ๎้โฌ็ไฝฒโฌๆป ็ดช็ๆๆนก้็ฒ็ + ๆฉๆฏ๎้่ทบ็้ๆณโฌๆฟๆฎ JS-SDK ๆตฃๆป่ด็๎ กโ้ฉ่น๎ ็็ฌๆฆ
Qin ้จๅซๅ็ๅ๎็โ ็ดฐ
- ็๎ กโ็ๅฆ็ดฐJS/ESM ็๎ ็กถ็ๆฐๆณฆ้ๅงarser/AST/็๎ ็ฎๅฆซโฌ้ใฏ็ด
- ๆฉๆฏ๎้่ทบ็ฐ้ๆฐฌ้ฉ้็ๆฃค้?JS-SDK้ๅ ๎ง
console/Math/JSON/Object้? - ้ชๅฒๅฝด็ๅฆ็ด้ๅบฃ๎ฌ้ๅค็ดฐJVM ๆฉๆฏ๎้ๅ ๅฝฒ็ๅชๆค Java/JDK ้ณ่ๅง้?
- ้ชๅฒๅฝด็ๅฆ็ด้ๅถ๎ฌ้ๅค็ดฐๅจดๅฟ๎้ฃใจ็น็ๅฒ็ดWeb ้ชๅฒๅฝด้ณ่ๅง้?
็ๆ๎ ธ้็ทๅฏ้?
- ็๎ ็กถ็ไปๅบ JS ๆถโฌ้ท่พพ็ด็๎ ็ฎๆทๆฟๅฏ้๎ๅธถ็ๆฐๆณฆ
- ้ชๅฒๅฝด้ณ่ๅง้ๅ็ฐ้ ๆ๎้ๅฑผ็ฌ้ถ?Node ็ๅซๅฏๅฏฎ้ธฟ๎็ฏ๏นๅ Qin
- ้ๅ ็น็ไฝธๅข ้ๅบฃ๎ฌๆถโฌ้ทๅฏธๆฎๅฏฎโฌ้ๆ็ถๆฅ ๅฒ็ด้ๅถโฌๆญ๎้ตโ็้ๅงๅฏๆดๆน๎ซ้ฉๆ ญๆฝฐ
- Java 25 LTS - ้โฌ้ไผดๆฑ้็ธๆฎ้ธไฝบๅข้๎็ด้๎ๅฏ้?2033 ้ช่พพ็ด
- Flexible Constructor Bodies (JEP 513) - ้ฐๅถ็ๆฅ ๅฒ็้ๆ็จ้?
- Module Import Declarations (JEP 511) - ๆต ๏ฝ็้ๅฏธ็ๅจฒ?
- Primitive Patterns (JEP 507) - ็ปซ่ฏฒ็ท็นๅคๅ้ฌั๎ๅฏฎ?
- Structured Concurrency (JEP 505) - ้ช่ทบๅฝ้ฌัๅ ้ปๆฌๅด 3-5x
- AOT Method Profiling (JEP 515) - ้๎ๅงฉ้ซ็ทๅฎณ้ปๆฌๅด 2-3x
- Compact Object Headers (JEP 519) - ้ๅญ็จ้็ตๆค้ๅฟ็ฏ 20-30%
| ้ธๅจ็ฃ | Java 17 | Java 25 | ้ปๆฌๅด |
|---|---|---|---|
| CLI ้๎ๅงฉ้ๅ ๆฃฟ | 800ms | 300ms | 2.7x ้ฟ? |
| ้ชๆฐ๎็ผๆ ฌ็ง (10 ้ๅฆๆฌข) | 5.2s | 1.8s | 2.9x ้ฆๆฎ |
| ้ๅญ็จ้็ตๆค | 180MB | 135MB | -25% ้ฆๆ |
| ๆต ๏ฝ็้ฒ? | 3500 ็? | 2100 ็? | -40% ้ฆๆ |
- Java 25 or higher (Download)
- Maven 3.8+ (้๎โฌๅค็ด้ขใค็ฐฌๆธๆฟ็ฆๆถๅฌญๆต)
# Windows
.\build-java.bat
# Linux/macOS
./build-java.sh# ้ใงๆน
็ฏ๎ผๅงช
java -cp ".qin\classes;lib\gson-2.10.1.jar" com.qin.cli.QinCli help
# ็ผๆ ฌ็งๆคคๅญๆดฐ
java -cp ".qin\classes;lib\gson-2.10.1.jar" com.qin.cli.QinCli compile
# ๆฉๆฏ๎ๆคคๅญๆดฐ
java -cp ".qin\classes;lib\gson-2.10.1.jar" com.qin.cli.QinCli runWindows (PowerShell):
# ๅจฃ่ฏฒๅง้?PowerShell Profile
function qin { java -cp "D:\path\to\qin\.qin\classes;D:\path\to\qin\lib\gson-2.10.1.jar" com.qin.cli.QinCli $args }Linux/macOS (Bash):
# ๅจฃ่ฏฒๅง้?~/.bashrc or ~/.zshrc
alias qin='java -cp "/path/to/qin/build/classes:/path/to/qin/lib/gson-2.10.1.jar" com.qin.cli.QinCli'้่ทบๆ็ๅๅฝฒๆต ใงๆดฟ้บใคๅจ้ข๎็ดฐ
qin compile
qin run
qin build- New package:
packages/qin-plugin-jite - Dev entry class:
com.qin.jite.JiteDevMain qin devnow prefers Jite runtime for.jsprojects- If
qin-plugin-jiteis not on classpath, CLI falls back tocom.qin.runtime.core.QinFullstackMain --dev
- Path:
packages/exmaples/jitedemo - Dependency:
com.qin:qin-plugin-jite - Run inside demo folder:
qin devOpen http://localhost:18080.
qin.config.js ้?Qin ้จๅฏใ้ฉ?manifest้?
็นๅจ็ถ้ๅถ
ๆ้่ตๅฃ้ทๅญๆด็ปซๆไบด็๏ฝ็ดฐ
- ้ๅฎ็ซป้?- ๆธๆฟ็ฆๆพน็ๆง้ใฅๅฝ
- workspace / module root ้ปๅฟๅ ช
- runtime / build / entry ้ฐๅถ็้?
entry่คฐๆณๅข ้๎ๅฏ้? - Qin source entry:
.qin้ไนฃ.js้ไนฃ.mjs้ไนฃ.ts` - Java host entry:
.java
qin run ้็ฒๅผฌ้็ๆคๆตผๆจบๅ็่ฏฒๅฝๆฉๆฌๅท้จ?entry้?
{
"name": "my-app",
"version": "1.0.0",
"description": "My awesome Java 25 app",
"entry": "main/main.qin",
"dependencies": {
"org.springframework.boot:spring-boot-starter-web": "4.0.6",
"com.github.ben-manes.caffeine:caffeine": "3.1.8"
},
"devDependencies": {
"org.junit.jupiter:junit-jupiter": "5.10.1"
},
"repositories": [
{
"id": "aliyun",
"url": "https://maven.aliyun.com/repository/public"
},
{
"id": "central",
"url": "https://repo1.maven.org/maven2"
}
],
"java": {
"version": "25",
"sourceDir": "src/main/java",
"testDir": "src/test/java",
"outputDir": "target/classes",
"encoding": "UTF-8"
},
"output": {
"dir": "dist",
"jarName": "my-app.jar",
"fatJar": true
}
}| ้ๆๆค | ็ๅญๆง | ็ป่ฝฐ็ทฅ |
|---|---|---|
compile |
็ผๆ ฌ็ง Java ๆคคๅญๆดฐ | qin compile |
run |
็ผๆ ฌ็ง้ชๆฐ็น็? | qin run / qin run Test.java / qin run main/main.qin |
dev |
ๅฏฎโฌ้ๆฤๅฏฎๅฟฅ็ดQin ้ๆ ๎ฌ้?+ ้ท๎ๅงฉ้้ๆ้? | qin dev / qin dev main/main.qin |
build |
้ๅซ็ผๆตั ๅขฟ้ๅava: JAR / Qin: fullstack ๆตั ๅขฟ้? | qin build / qin build main/main.qin |
test |
ๆฉๆฏ๎ๅจดๅฌญ็ฏ | qin test |
sync |
้ๅฑพ๎ๆธๆฟ็ฆ | qin sync |
clean |
ๅจๅฏๆ้ๅซ็ผๆตั ๅขฟ | qin clean |
init |
้ๆฟ๎้ๆ ญใ้ฉ? | qin init |
env |
้๎๎จๅฆซโฌ้? | qin env |
# ๆฉๆฏ๎ๆคคๅญๆดฐ้ใฅๅฝ้ๅฌin.config.json ๆถ๎
ๆฎ entry้?
qin run
# ๆฉๆฏ๎้ธๅง็พ้จ?Java ้ๅฆๆฌข
qin run src/main/java/com/example/Test.java
# ๆฉๆฏ๎้ธๅง็พ้จ?Qin ้ๅฆๆฌข
qin run main/main.qin
# ๆฉๆฏ๎้ธๅง็พ้ๅฆๆฌข้ชๆต็ดถ้ซๆๅผฌ้?
qin run MyTest.java arg1 arg2ๆฉๆฏ๎้ๅๅฝ็ๅซๅฏ้ๅ ข็ฒบๆถโฌ้ๅค็ดฐ
-
ๆตผ็ฒๅ้ฉ๎ฝ็ฃ้ๅๆ้่ฎน็ดฐๆตผๆจบๅ้ปๆๆฌข็๏ฝ็ฝ้ๅฑฝๅพๅจ?
.js้ๅฑพๆธถ้ๅบขๅฏ Java ้ใฅๅฝๆพถๅญๆ้? -
ๆถๅถ็ดถ้ๅๆ้่ฎน็ดฐๆตผๆจบๅ็่ฏฒๅฝ
qin.config.js้จ?entry้ๆถๅซขๆถ?.qin/.js/.mjs/.ts็ง?Qin ๆฉๆฏ๎้่ฎน็ด้๏นๅฏ้ธ?Java host ้ใฅๅฝๆพถๅญๆ้?run/dev้ๅๅ้? -
qin run้ๆฐซ็ซดๅจโ็ฏๅฏคๅๆ้๎ๅงฉ้ๅฑผ็ฌ้ฉๆๆ้ๅฆๆฌข้ๆจบๅฏฒ้? -
qin dev้ๆฐฌๅด็ป๎ๅฝๅฏฎโฌ้ๆๆน้โ ็ดๆฆๆจฟ๎ ป้ๅฒ๎ฌ้๏ฝๅฝๆธ?API + ้ๆฌโฌไพใ้๎ฎ็ด้ๅฒๆด้?.js/.html/.css้ๆจปๆดฟ้ชๆฐๅ้ใฉๅธ็ผๆ ฌ็งๆถๅบข็ฅป็ๅ ๆซ้้ๆ้? -
็?MVP ้จๅฌ็ณ่นๅฎๆผ็บ๎ไบ Qin + Java ๆฉๆฏ๎้ๆต่ดๆถไผ็ด้ๅถ๎ฌ้ข?Qin ้็บๆ dev server ้?Qin frontend pipeline ้ต่ฏๆต้ๅฑผ็ฌ้ซๆฐณ็น Node/Vite ็ๆฏ็น็ปๅฌซห้บใฃโฌ? ้ๅซ็ผ้ๅๅฝ็ๅซๅฏ้ๅ ข็ฒบๆถโฌ้ๅค็ดฐ
-
qin build้ฆใฆ๎ ๅจดๅฌชๅ.js้ใฅๅฝ้่ฎน็ดๆตผๆฐณ่ Qin fullstack build-only ๅจดไฝบโผ้? -
ๆฆๆจฟ๎ ปๆๆณๅญ้ฉ๎ผ็ถ้ๆญdist/fullstack
้ๅฑฝๅพๆถ?server-classes/็ๆจปๆ้ๅบฃ๎ฌ.class้ๅฎweb/็ๆจปๆ้ๅถ๎ฌ้ๅซ็ผๆตั ๅขฟ้ๅ ๆapp.js้ๅคโฌ? -
้๎ๆค
-o/--output็ๅๆดๆๆณๅญ้ๅญๆดฐ่คฐๆโฌ?
Qin ๆตฃ่ทจๆค *javax.tools API + ้ๅ ๆฃฟ้ด่ซ็ฎๆ? ็น็ตๅน้ ้ธฟๅ ๆพง็บๅบ็ผๆ ฌ็ง้?
- ้?*้
้ธฟๅ
ๅฆซโฌๅจด? - ้๎็ดช็ๆๆ
จ้็ก
็น้จๅฌๆๆต ่ฎน็ดๅงฃๆ็ท
.java้?.class้จๅชๆ จ้่งๆค้่พพ็ด - ้?้ท๎ๅงฉๆธๆฟ็ฆ -
javac้ท๎ๅงฉๆพถๅญๆๆธๆฟ็ฆ้ๅฆๆฌข้จๅญ็ดช็? - ้?*้ๅ ๅค็ผ? - ้็ปๆธถๆฃฐๆฟ๎ป้ฐๅถ็้ๅฑฝ็ด็ป ๅๅต้ข?
- ้?*่น๎ฆโฌ็ทๆทๆด? - ้็ฑๆ จ้่งๆค็บๅฎ ็น็ผๆ ฌ็ง้ๅฒ็้ๅฎ ็น็?
*็น็ตๅน้็บๆ้?
// ๅงฃๆ็ทๅงฃๅฟ้ .java ้ๅฆๆฌข้ๅฑฝ๎ฎๆด?.class ้ๅฆๆฌข้จๅฌๆค้ๅญๅ
private boolean isModified(String javaFilePath) {
Path classFile = getClassFilePath(javaFilePath);
if (!Files.exists(classFile)) return true;
return Files.getLastModifiedTime(javaFile) > Files.getLastModifiedTime(classFile);
}
// ๆตฃ่ทจๆค javax.tools API ็ผๆ ฌ็ง
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
compiler.getTask(...).call();*้ฌัๅ ้ปๆฌๅด้?
| ้ฆ็ๆซ | ้ใฉๅบ็ผๆ ฌ็ง | ๆพง็บๅบ็ผๆ ฌ็ง | ้ปๆฌๅด |
|---|---|---|---|
| ้็ฑๆ จ้? | 3.2s | 0.1s | 32x ้ฟ? |
| ๆท๎ฝๆผ 1 ๆถ๎ ๆๆต ? | 3.2s | 0.5s | 6.4x ้ฆๆฎ |
| ๆท๎ฝๆผ 10 ๆถ๎ ๆๆต ? | 3.2s | 1.8s | 1.8x ้ฟ? |
Qin ้ฆใฆ็กๆถ๎ใ้ฉ๎พๆฎ .qin/classpath.json ๆถ๎
็ดฆ็ๆจน็ทท็งๆ ฌะ้ๆฎ็ฒจ้ๆป็ดฐ
{
"classpath": [
"D:/project/subhuti-java/build/classes",
"C:/Users/qinky/.qin/libs/com.google.code.gson/gson-2.10.1/gson-2.10.1.jar"
],
"lastUpdated": "2025-12-30T07:10:32Z"
}*ๅฎธใค็ถๅจดไฝบโผ้?
qin run/sync
้ซ?
ๅฆซโฌ้?.qin/classpath.json ้๎ๆ็ๆจบๆนช
้ซ?
ๅงฃๆ็ท็ผๆณ็จ้ๅ ๆฃฟ vs qin.config.js ๆท๎ฝๆผ้ๅ ๆฃฟ
้ซ?
็ผๆณ็จ้ๅคๆฅ ้ซ?้ฉๅญๅธดๆตฃ่ทจๆค้ๅ ๆฉ้ซ็ทๆ้๎็ด
็ผๆณ็จ้็ณๆฅ ้ซ?้ฒๅถๆ็๏ฝ็ฝๆธๆฟ็ฆ้ช่ตๆดฟ้ๆฎ็ดฆ็?
*ๆตผๆจบๅจ้?
- ้ฟ?ๆฃฃๆ จ๎ผๆฉๆฏ๎ - ็๏ฝ็ฝๆธๆฟ็ฆ + ้ข็ธๅ็ผๆณ็จ
- ้ฆๆฎ ้ๅบฃ็ปๆฉๆฏ๎ - ้ฉๅญๅธด็่ค็ดฆ็ๆฉ็ด็ปๆ้ช้๎ๅงฉ
- ้ฆๆง ้ท๎ๅงฉ้้ๆ - ๆท๎ฝๆผ
qin.config.js้ๅบคๅ้ใฉๅธ้ๆะ้?
Qin ้ท๎ๅงฉ้ๆ ๅน้ชๆต็ดญ้ๅ ๅจ้ขใฆๆนฐ้ฆไผดใ้ฉ๎ป็ทท็งๆ ต็ด้ฌๅฎๅคๆต ?Maven ๆถๅฌญๆต้?
*้ท๎ๅงฉ้ๆ ๅน็ปๆ ซๆ้?
- ๆต ๅบก็ถ้ๅถๆดฐ่คฐๆๆๆถๅฉ็
ก้ต็ฌๅข้ๅคๅฏ้?
qin.config.js้จๅญๆดฐ่คฐ? - ้ต๎ฃๅผฟๅงฃๅฟ้้ฉ๎ผ็ถ้จๅซๆ็ปพัใ้ฉ?
- ้ๅฝๅคๆธๆฟ็ฆ้จ?
groupId:artifactId - ็่พซ็นๆตผๆจบๅ้ๅ ฃ็น้จๅฏใ้ฉ๎ฟ๎ซ้ฉๆ ฌ็น้จๅซๆ้ๅถใ้ฉ๎็ด
*็ป่ฝฐ็ทฅ้?
d:/project/
้นๆบพๆข้นโฌ slime-java/
้น? ้นๆบพๆข้นโฌ subhuti-java/ # com.subhuti:subhuti-java
้น? ้น? ้นๆบพๆข้นโฌ qin.config.js
้น? ้น? ้นๆบๆข้นโฌ build/classes/ ้ซ?้๎ๆนดๆธๆฟ็ฆ็บ๎็ท
้น? ้นๆบพๆข้นโฌ slime-token/ # com.slime:slime-token
้น? ้น? ้นๆบๆข้นโฌ build/classes/
้น? ้นๆบๆข้นโฌ slime-parser/ # ๆธๆฟ็ฆๆถๅฉๆฝฐๆถใ้ๆคคๅญๆดฐ
้น? ้นๆบๆข้นโฌ qin.config.js
้ฆ?slime-parser ๆถ๎
จ็ดฐ
{
"dependencies": {
"com.subhuti:subhuti-java": "1.0.0-SNAPSHOT",
"com.slime:slime-token": "1.0.0"
}
}้ตั๎ qin sync ๆๆณๅญ้?
้ซ?Syncing dependencies...
้ซ?Found 2 local dependencies
้?Dependencies synced (2 local, 0 remote)
Cache: .qin/classpath.json
*ๆตผๆจบๅจ้?
- ้ฆๆฎ ้็ปๆธถ้ๆ็ซท - ้๎ๆนดๅฏฎโฌ้ๆๆฃค้โฌ้ๆ็ซท้?Maven
- ้ฆๆง ็น็ดๆค้ๅญๆ - ๆท๎ฝๆผๆธๆฟ็ฆๆคคๅญๆดฐ็ปๅฌชๅต้ข็ธๆฅ
- ้ฆๆ ้บๅๆธท็ฏ๏น๎ - ๆถๅถ็ฌ ๆ่ฅๆนฐ้ฆๆฟๅก้ๅคๆฎๆคคๅญๆดฐ
- ้ฆๅน Monorepo ้ๅฌชใฝ - ๆพถโๅง้๎ๅฏๆพถๆฐถใ้ฉ๎ผไผๆตฃๆปๅฐฏ
qin run / qin sync
้ซ?
ๅฆซโฌ้ใค็ทท็งๆ ซ็ดฆ็?(.qin/classpath.json)
้ซ?
[็ผๆณ็จ้ๅคๆฅ]้นโฌ้นโฌ้นโฌ้นโฌ้นโฌ้นโฌ้นโฌ้นโฌ้นโฌ้นโฌ้นโฌ้นโฌ้นโฌ้นโฌ้นโฌ้น?
้ซ? ้ซ?
[็ผๆณ็จ้็ณๆฅ] ๆตฃ่ทจๆค็ผๆณ็จ
้ซ? ้ซ?
้๎ๆนดๆธๆฟ็ฆ็๏ฝ็ฝ ้ฉๅญๅธดๆฉๆฏ๎
(LocalProjectResolver)
้ซ?
้ตๆงๅ ้ซ?ๆตฃ่ทจๆค build/classes ็บ๎็ท
้๎
ๅฃ้?้ซ?้ๅช๎ๆถ้ธฟ็น็ปๅฌฉ็ทท็ง?
้ซ?
ๆฉๆป
โผๆธๆฟ็ฆ็๏ฝ็ฝ
(DependencyResolver + Coursier)
้ซ?
้ๅ ่้๎ๆนด+ๆฉๆป
โผ classpath
้ซ?
้ๆฌๅ .qin/classpath.json
้ซ?
ๆฉๆฏ๎็ปๅฌช็ฐญ
run ้ๆๆค้?sync ้ๆๆค้ๅ้ฉ้็จฟ็ธพๆธๆฟ็ฆ็๏ฝ็ฝ้ซๆ็ทซ้?
// run ้ๆๆค
private static void runProject(String[] args) {
String classpath = ensureDependenciesSynced(config); // ๆพถๅถๆค
runner.compileAndRun(classpath);
}
// sync ้ๆๆค
private static void syncDependencies() {
syncDependenciesCore(config); // ้็จฟ็ธพ้ซๆ็ทซ
}
// ้ๅ้ฉ้จๅฌ็ณ่นๅฎโฌๆ็ทซ
private static String syncDependenciesCore(QinConfig config) {
// 1. ้๎ๆนดๆธๆฟ็ฆ็๏ฝ็ฝ
LocalProjectResolver.ResolutionResult localResult = ...;
// 2. ๆฉๆป
โผๆธๆฟ็ฆ็๏ฝ็ฝ้ๅ ็ฒ้๎ๆนช้๎ๆนด้ตๆงๅ้จๅถ็ด
if (!localResult.remoteDependencies.isEmpty()) {
DependencyResolver resolver = ...;
}
// 3. ้ข็ธๅ้ชๅ็ดฆ็?classpath
return classpath;
}Qin ้ปๆช็ทต IntelliJ IDEA ้ปๆๆฌข้ๅฑฝ็้?IDE ้็ต็ดณ้ๅๅ้?
*้ท๎ๅงฉ้็ปๅ ้?
- ้?้ท๎ๅงฉ้ๅฑพ๎ - ้ตๆณ็ดๆคคๅญๆดฐ้ๆฐๅ้ใฆๅขฝ็?
qin sync - ้?*ๆดๆปๅค็ผ๎พๆ้ด? - ้ท๎ๅงฉ้ข็ธๅ
.idea/libraries/*.xml - ้?็ผๆ ฌ็งๆๆณๅญ้ฐๅถ็ - ้ท๎ๅงฉๆตฃ่ทจๆค
build/classes้ๅ ็ฌ qin ๆถโฌ้ท่พพ็ด - ้?Monorepo ้๎ๅฏ - ้ท๎ๅงฉ้ต๎ฃๅผฟ้ตโฌ้ๅค็ๆคคๅญๆดฐ
*็นๅค๎้?
# ้ๅซ็ผ้ปๆๆฌข
cd packages/qin-idea-plugin-debug
./gradlew buildPlugin
# ็นๅค๎้ๆฌผDEA ้ซ?Settings ้ซ?Plugins ้ซ?้ฟๆฌ็ฌ ้ซ?Install from Disk
# ้ซๅคๅซจ build/distributions/qin-idea-plugin-debug-x.x.x.zip*ๅฎธใค็ถ้็บๆ้?
IDEA ้ตๆณ็ดๆคคๅญๆดฐ
้ซ?
้ๆ็ฌ้ใฆๅฃ workspace root้?idea/.vscode/.git้?
้ซ?
้ๆ็ฌ
้ซๆ็ถ้ต๎ฃๅผฟ้ตโฌ้?qin.config.js้ๅ ๆธถๆพถ?5 ็ๅฆ็ด
้ซ?
ๆถ็็กๆถ๎ใ้ฉ๎ฝๅขฝ็?qin sync
้ซ?
้ข็ธๅ .idea/libraries/*.xml
้ซ?
้ๅญๆ .iml ้ๅฆๆฌข้ๅ ๅ้็ฒ็ฐฑๅฏฎๆ ๆค + ้ฐๅถ็ๆๆณๅญ็บ๎็ท้?
้ซ?
้้ๆ IDEA ๆคคๅญๆดฐๅฆฏโณ็ท
Qin ้็บๆ้๎ๅฏ Monorepo้ๅ ๅดๆต ๆณ็ฐฑๆพถๆฐถใ้ฉ๎็ดๅฆฏโณ็ดก้?
*้ฉ๎ผ็ถ็ผๆด็ฏ้?
workspace/
้นๆบพๆข้นโฌ .git/
้นๆบพๆข้นโฌ .idea/ # IDEA ๆคคๅญๆดฐ้ๅง็น
้นๆบพๆข้นโฌ project-a/
้น? ้นๆบๆข้นโฌ qin.config.js
้นๆบพๆข้นโฌ project-b/
้น? ้นๆบๆข้นโฌ qin.config.js
้นๆบพๆข้นโฌ packages/
้น? ้นๆบพๆข้นโฌ lib-1/
้น? ้น? ้นๆบๆข้นโฌ qin.config.js
้น? ้นๆบๆข้นโฌ lib-2/
้น? ้นๆบๆข้นโฌ qin.config.js
้นๆบๆข้นโฌ apps/
้นๆบๆข้นโฌ app-1/
้นๆบๆข้นโฌ qin.config.js
*้๎ๆนดๆธๆฟ็ฆ็๏ฝ็ฝ็ปๆ ซๆ้?
- ๆต ๅบก็ถ้ๅถๆดฐ่คฐๆๆๆถๅฉ็
ก้ต็ฌๅข้?
qin.config.js - ้ต๎ฃๅผฟ้ๅฒ้ช้ฉ๎ผ็ถ้จๅซๅพๆต ๆ ญใ้ฉ?
- ็่พซ็นๆตผๆจบๅ้ๆฐณ็น้จๅฏใ้ฉ๎ฟ๎ซ้ฉๆ ฌ็น้จๅซๆ้ๅถใ้ฉ?
*IDEA ้ปๆๆฌข้ต๎ฃๅผฟ็ปๆ ซๆ้?
- ้ๆ็ฌ้ตๆงๅ workspace root้ๅ ๆธถๆคค่ทบ็ฐ้จ?
.idea/.vscode/.git้ฉ๎ผ็ถ้? - ๆต ?workspace root ้ๆ็ฌ
้ซๆ็ถ้ต๎ฃๅผฟ้ตโฌ้?
qin.config.js - ๆถ็็กๆถ๎ๅฝ้ๆฎๆฎๆคคๅญๆดฐ้ท๎ๅงฉ้ตั๎ sync
*้ฐๅถ็็ป่ฝฐ็ทฅ้?
// project-a/qin.config.js
{
"name": "com.example:project-a",
"version": "1.0.0",
"dependencies": {
"com.example:lib-1": "1.0.0", // ้ท๎ๅงฉๆตฃ่ทจๆค้๎ๆนด ../packages/lib-1
"com.example:lib-2": "1.0.0" // ้ท๎ๅงฉๆตฃ่ทจๆค้๎ๆนด ../packages/lib-2
}
}// ้?Java 25 ้ๆฎๅฃ้ฌ?
public record QinConfig(String name, String version, Map<String, String> dependencies) {
public QinConfig {
// ้๎ไบ้ฆ?super() ้ๅถ็็ไฝธๅผฌ้ๅธฎ็ด
if (name == null || name.isBlank()) {
throw new IllegalArgumentException("name cannot be blank");
}
// ้ปๆช็ทตๆฆๆจฟ๎
ป้?
dependencies = dependencies != null ? Map.copyOf(dependencies) : Map.of();
}
}// ้?Java 25 - ้ฉ็ๆนฐ็ปซ่ฏฒ็ทๅฆฏโณ็ดก้ๅฝๅค
String result = switch (value) {
case int i when i > 0 -> "positive: " + i;
case long l -> "long value: " + l;
case double d -> "double value: " + d;
default -> "other";
};// ้?Java 25 - ็ผๆด็ฏ้ๆ ง่้?
try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
var task1 = scope.fork(() -> downloadDependency("lib1"));
var task2 = scope.fork(() -> downloadDependency("lib2"));
scope.join().throwIfFailed(); // ็ผ็ถ็ซดๅฏฎๅ็ถๆพถๅญๆ
return List.of(task1.get(), task2.get());
}my-project/
้นๆบพๆข้นโฌ qin.config.js # Qin ้ฐๅถ็
้นๆบพๆข้นโฌ src/
้น? ้นๆบพๆข้นโฌ main/java/ # ๅฉงๆฎ็
้น? ้น? ้นๆบๆข้นโฌ com/myapp/
้น? ้น? ้นๆบๆข้นโฌ Main.java
้น? ้นๆบๆข้นโฌ test/java/ # ๅจดๅฌญ็ฏ
้นๆบพๆข้นโฌ build/
้น? ้นๆบๆข้นโฌ classes/ # ็ผๆ ฌ็งๆๆณๅญ (OUTPUT_DIR)
้นๆบพๆข้นโฌ .qin/ # Qin ้ฐๅถ็้ฉ๎ผ็ถ
้น? ้นๆบพๆข้นโฌ classpath.json # ๆธๆฟ็ฆ็ผๆณ็จ (CLASSPATH_CACHE)
้น? ้นๆบๆข้นโฌ libs/ # ้๎ๆนดๆธๆฟ็ฆ้พ็ฌๅธด (LIBS_DIR)
้น? ้นๆบๆข้นโฌ com.google.code.gson/
้น? ้นๆบๆข้นโฌ gson-2.10.1/ -> ~/.qin/libs/.../
้นๆบๆข้นโฌ dist/
้นๆบๆข้นโฌ my-app.jar # Fat JAR
~/.qin/
้นๆบๆข้นโฌ libs/ # ้ใฅ็ฌๆธๆฟ็ฆ็ผๆณ็จ (GLOBAL_LIBS_DIR)
้นๆบๆข้นโฌ com.google.code.gson/
้นๆบๆข้นโฌ gson-2.10.1/
้นๆบๆข้นโฌ gson-2.10.1.jar
| ็ฏๆๅบ | ้? | ็ๅญๆง |
|---|---|---|
| OUTPUT_DIR | build/classes |
็ผๆ ฌ็งๆๆณๅญ้ฉ๎ผ็ถ |
| QIN_DIR | .qin |
Qin้ฐๅถ็้ฉ๎ผ็ถ |
| CLASSPATH_CACHE | .qin/classpath.json |
ๆธๆฟ็ฆ็ผๆณ็จ้ๅฆๆฌข |
| LIBS_DIR | .qin/libs |
ๆธๆฟ็ฆๆดๆถๆดฐ่คฐ? |
qin/
้นๆบพๆข้นโฌ src/java-rewrite/ # Java 25 ๅฉงๆฎ็
้น? ้นๆบๆข้นโฌ com/qin/
้น? ้นๆบพๆข้นโฌ types/ # ้ฐๅถ็็ปซ่ฏฒ็ท้ๅงecords้?
้น? ้นๆบพๆข้นโฌ core/ # ้็จฟ็ธพๅฆฏโณๆฝก
้น? ้นๆบพๆข้นโฌ commands/ # ้ๆๆค็น็ตๅน
้น? ้นๆบพๆข้นโฌ cli/ # CLI ้ใฅๅฝ
้น? ้นๆบๆข้นโฌ java/ # Java ๅฎธใฅๅฟ
้นๆบพๆข้นโฌ .qin/
้น? ้นๆบๆข้นโฌ classes/ # ็ผๆ ฌ็งๆๆณๅญ
้นๆบพๆข้นโฌ lib/
้น? ้นๆบๆข้นโฌ gson-2.10.1.jar # ้๎็ซดๆธๆฟ็ฆ
้นๆบๆข้นโฌ build-java.bat # ้ๅซ็ผ้ดๆฐญๆนฐ
้็ปๅ : ็ผ็ถ็ซด็ป ๏ผๆ้ตโฌ้ๅค็พๅฏฐๅซ็ถ้ฒ?
public static final String OUTPUT_DIR = "build/classes";
public static final String LIBS_DIR = ".qin/libs";**ๆถ่ฝฐ็ฒๆถๅ ฅๆธถ็?*: ้ฌๅฎๅค็บญ๎็ดช้ฎไพ็ด็ผ็ถ็ซด็บ๎็ท้ฐๅถ็้ๅฑพๆๆธ่ทจๆทฎ้ถใ ๆฐๆท๎ฝๆผ
้็ปๅ : ้ๅซ็ผ็ผๆ ฌ็ง้ๅฒ็น็ๅฑพๆค้จๅขlasspath
buildCompileClasspath()- ็ผๆ ฌ็ง้็ฆผlasspath้ๅ ๅฏ้๎ฃๆนฐ้ฆไผดใ้ฉ?ๆฉๆป โผๆธๆฟ็ฆ้?buildRuntimeClasspath()- ๆฉๆฏ๎้็ฆผlasspath
**ๆถ่ฝฐ็ฒๆถๅ ฅๆธถ็?*: classpath้ๅซ็ผ้ซๆ็ทซๆพถๅถๆฝ ้ๅ ๆนฐ้ฆไผดใ้ฉ๎ผๅฝ้่ฌโฌไฝท็ทท็งๆ ฌะ้ๆถ็ด้ๅฒๅซญ็ปๅฌชๅญ้ใฆๅฝๆฅๆจบๅฝฒ็ผๅญๅงข้ฌ?
้็ปๅ : Javaๅฉงๆญๆๆต ๅ็ดช็?
compile()- ๆตฃ่ทจๆคjavax.tools API็ผๆ ฌ็งfilterModifiedFiles()- ๆพง็บๅบ็ผๆ ฌ็ง้ๅ ๅฝง็ผๆ ฌ็งๆท๎ฝๆผ้จๅฌๆๆต ่ฎน็ดfindJavaFiles()- ้ใฆๅฃJava้ๅฆๆฌข
**ๆถ่ฝฐ็ฒๆถๅ ฅๆธถ็?*: ็ไฝฝ๎ๆพถๅถๆฝ ้จๅญ็ดช็ๆฆโฌๆ็ทซ้ๅฑพๆฎ้ธไฝธ๎้ฒๅฟ็ดช็ๆๅฝ้ๅจโฌัๅ
้็ปๅ : ๆพถๅถ ๅ็งๅฌ็ฐฎ้ๅฆๆฌข้ๆ็ทญ้่นๆดฐ่คฐ?
- ้ใฆๅฃๆพถๆฐซ้้๎ๅ
้จๅฎ็ฅซๅฉงๆฎๆดฐ่คฐๆช็ด
src/resources,src/main/resources้? - ้ซๆ็ถๆพถๅถ ๅ้ฉ๎ผ็ถ
**ๆถ่ฝฐ็ฒๆถๅ ฅๆธถ็?*: ็งๅฌ็ฐฎ้ๅฆๆฌขๆพถๅญๆ้๎ๅซญ็ปๅฌฌๆฎ้็ปๅ ้ๅฑผ็ฌ็ผๆ ฌ็ง้ซๆ็ทซ้ๅ๎
้็ปๅ : ๆฉๆฏ๎็ผๆ ฌ็ง้ๅบฃๆฎJava็ปๅฌช็ฐญ
run()- ๆฉๆฏ๎้ธๅง็พ็ปซ?runFile()- ๆฉๆฏ๎้ธๅง็พJava้ๅฆๆฌขjavaFilePathToClassName()- ็บ๎็ทๆ๎่ขซ้?
**ๆถ่ฝฐ็ฒๆถๅ ฅๆธถ็?*: ๆฉๆฏ๎้ซๆ็ทซ้๎็้ๅฑพๆฎ้ธไฝธ๎ฟ็ปๅถ็น็ๅฑพๆๅฏฎ?
้็ปๅ : ้ๅฟ็ๆถๅฉ ๅ ช4ๆถ๎่ขซ้ๅฑพๅฝๆธๆถ็ฒบๆถโฌ้บใฅๅฝ
public CompileResult compile() {
// 1. ็ผๆ ฌ็งๆธๆฟ็ฆ
// 2. ้ใฆๅฃJava้ๅฆๆฌข
// 3. ๆพถๅถ
ๅ็งๅฌ็ฐฎ
// 4. ๆพง็บๅบ็ผๆ ฌ็ง
}**ๆถ่ฝฐ็ฒๆถๅ ฅๆธถ็?*: ๆทๆฟๅฏ็ป โฌ้ๆ ๆฎ็ๅชๆค้บใฅๅฝ้ๅฒๆฎฃ้ๅฟๅด้ฎใฅ๎ฒ้ๅโฌ?
้็ปๅ : ้ท๎ๅงฉ้ๆ ๅน้๎ๆนดๆคคๅญๆดฐๆธๆฟ็ฆ
- ้ๆ็ฌ้ใฆๅฃ้ตโฌ้ๅกนin.config.json
- ้ๅฝๅคgroupId:artifactId
- ็่พซ็นๆตผๆจบๅ
**ๆถ่ฝฐ็ฒๆถๅ ฅๆธถ็?*: Monorepo้๎ๅฏ้ๅฒไผฉ้ๅถ ๅฝ็ฏๅจๅMavenๆต ๆณ็ฐฑ
้็ปๅ : ๆตฃ่ทจๆคCoursier็๏ฝ็ฝMavenๆธๆฟ็ฆ
- ๆถๅฌญๆตjar้็/.qin/libs
- ็ผๆณ็จๆธๆฟ็ฆ็๏ฝ็ฝ็ผๆด็
**ๆถ่ฝฐ็ฒๆถๅ ฅๆธถ็?*: ้ท๎ๅงฉๆถๅฌญๆต้ๅฒ๎ ธ้ๅ็น็ปๅฌฉ็ทท็ง?
ๆตฃ่ทจๆคJava 25 Records็นๆฐซ็ฎ้ฐๅถ็็ปซ่ฏฒ็ท้?
public record QinConfig(
String name,
String version,
Map<String, String> dependencies
) {}**ๆถ่ฝฐ็ฒๆถๅ ฅๆธถ็?*: ๆถๅถ ๅฝฒ้ๆฉๅค็ผ๎็ด็ปซ่ฏฒ็ท็นๅคๅ้ๅฑผๅฌ้ฎไฝบ็ๅจฒ?
้็ปๅ : ้ๆๆค็ๅฑฝๅ้๏ฝ็ด็๏ฝ็ฝ้ๆๆค้ๅฑฝๅผฌ้?
qin compile ้ซ?CompileCommand
qin run ้ซ?RunCommand
qin build ้ซ?BuildCommand
**ๆถ่ฝฐ็ฒๆถๅ ฅๆธถ็?*: ็ผ็ถ็ซด้จๅซๆกๆต ใ๎้บใฅๅฝ้ๅฒๆค้ดๅณฐๅผธๆฟ?
- ้ฑๅฒ็้ๆ็ซด: ๅงฃๅฟ้็ปซ่ฏฒๅฝง็็ป็ๆถโฌๆต ๆต็ฐจ
- ๆธๆฟ็ฆๅจใฅๅ: ้ซๆฐณ็น้ๅฏโฌ็ฒๅฑ้้ข็ดถ้ซๆ็ทท็ง?
- ้ใ ๆ้บใฅๅฝ: ๆตฃ่ทจๆค้ถๅ่็ปซ่ฏฒ็ท้ๅฑผ็ฉถๆตๅบข็ฅด็ๆๆฐ้ตโ็
- ็ฏๆๅบ็ป ๏ผๆ: ้ตโฌ้ๅค็พๅฏฐๅฏโฌๆฐณ็นQinPaths็ผ็ถ็ซด็ป ๏ผๆ
### ็ผๆ ฌ็ง
```bash
# ็ผๆ ฌ็ง Qin ้๎้ฉ
.\build-java.bat
# ๆๆณๅญ้ๆญuild/classes/
# ๆตฃ่ทจๆค Qin ็ผๆ ฌ็งๅจดๅฌญ็ฏๆคคๅญๆดฐ
cd examples/hello-java
..\..\qin.bat compile
..\..\qin.bat run- JSON ้ฐๅถ็ - ้ๅฉๅ XML้ๅฑพๅซข้ถ?JSON
- ๆธๆฟ็ฆ็ป ๏ผๆ - npm ๆคๅบข็ธ้จๅช็ทท็งๆ ฌ๎ขๅจ?
- ๆพง็บๅบ็ผๆ ฌ็ง - javax.tools API + ้ๅ ๆฃฟ้ด็ญน็ด32x ้ฌัๅ ้ปๆฌๅด
- ๆธๆฟ็ฆ็ผๆณ็จ - .qin/classpath.json ้ท๎ๅงฉ็ผๆณ็จ้ๅฒ๎็ปพัๆ้?
- ้๎ๆนดๆธๆฟ็ฆๆตผๆจบๅ - ้ท๎ๅงฉ้ๆ ๅน้๎ๆนดๆคคๅญๆดฐ้ๅฑพๆฃค้โฌ้ๆ็ซท้?Maven
- Fat JAR ้ๅซ็ผ - ๆถโฌ้ฟ๎พๆ้ดๆฌๅฝฒ้ตั๎ JAR
- ๆฉๆฏ๎้ธๅง็พ้ๅฆๆฌข -
qin run Test.java/qin run main/main.qin - ้ชๆฐ๎็ผๆ ฌ็ง - Virtual Threads ้็ปโฌ?
- *้๎ ขๅธๆ? - ๅฏฎโฌ้ๆฤๅฏฎๅฟๅ้ใฉๅธ้ๆฎ็ดช็?
- Monorepo ้๎ๅฏ - ๆพถๆฐถใ้ฉ๎พ๎ ธ้?
- Records ๆต ๏ฝๆต POJO - ๆต ๏ฝ็้ๅฟ็ฏ 60%
- Flexible Constructors - ้ๆ็จ้ใงๆฎๆฅ ๅฒ็
- Pattern Matching - ้็ฟ ็ดญ้ๅฏๆฎ็ปซ่ฏฒ็ทๆพถๅญๆ
- Virtual Threads - 3-5x ้ช่ทบๅฝ้ฌัๅ
- Structured Concurrency - ้ๆๅฝฒ้็ตๆฎๅฏฎๅ๎
- AOT Profiling - 2-3x ้๎ๅงฉ้ซ็ทๅฎณ
- Compact Headers - 20-30% ้ๅญ็จ้บๅๆธท
- Java 25 ้ฒๅถ ๅ็โณๅ
- [Java 25 ้่งโฌั๎็๎ฃ(./docs/JAVA25_FEATURES.md)
- [้ฐๅถ็้ๅโฌๅ(./docs/CONFIG_REFERENCE.md)
- [้ปๆๆฌขๅฏฎโฌ้ๆ ฎ(./docs/PLUGIN_DEVELOPMENT.md)
ๅจใฃ็น็๏ผๅฐๆต ๏ฝ็้ไฝนๅงค้?Bug ้ดๆ จๅฝ้ๅ็ผ็๎็ด
MIT License - ้ใงๆน LICENSE ้ๅฆๆฌข
Built with ้ใ็ฌ using Java 25
Powered by Flexible Constructors, Virtual Threads, and Structured Concurrency
Qin is an ESM-first language/runtime implemented on Java/JVM. It is designed as a new language platform, not a Node.js compatibility layer.
More precisely:
- Qin borrows ESM as a source-language and module-design inspiration.
- Qin does not treat Node.js as its platform standard.
- Qin defines its own runtime boundary on top of Java/JVM.
Qin should be understood as:
- a Qin-owned programming language
- whose source experience is based on ESM / modern JavaScript-style syntax
- with Qin-specific syntax and semantic extensions
- with JVM as the primary backend/runtime kernel
- with fullstack targets across frontend and backend
In practical terms:
- backend Qin code compiles to JVM
.class - frontend Qin code can compile to JS for web targets
- Java is the host platform and ecosystem carrier
- Qin is the business language, not "Java source with different syntax"
So the most accurate short definition is:
- Qin is a fullstack, ESM-style, JVM language.
- ESM-first: Qin source uses ES-style syntax and ESM
import/exportas the primary module model. - Java/JVM kernel: backend compiles to JVM
.class(and can also emit JS for web targets). - Mixed-source Qin input: Qin accepts
.ts,.js, and.qinin the same workspace graph. .javaremains host/interoperability code for backend projects, not a Qin source suffix.- Node compatibility is optional and incremental: it is a compatibility layer for third-party packages, not the platform definition.
- Java-backed stdlib: runtime capabilities are implemented on top of Java standard library.
- Fullstack orientation: one language across
shared/, frontend, and backend, with target-specific backends. - Qin-owned standard: language/runtime semantics are defined by Qin itself, while Node-adjacent behavior can be added when needed.
Backend architecture note:
- Qin user-facing application model is documented in packages/qin-runtime-core/QIN_APP_MODEL.md.
- Qin server-side code is intended to stand on JVM +
.classecosystem support. - Node is not the backend foundation of Qin.
- Parsing ownership should belong to a Qin-owned parser layer (
qin-parser) built on top of sharedjava-slimeinfrastructure. - Qin language/target zoning is documented in packages/qin-runtime-core/QIN_LANGUAGE_TARGET_MODEL.md.
- JS/TS compatibility boundary is documented in packages/qin-runtime-core/QIN_JS_COMPATIBILITY_MODEL.md.
- npm compatibility grading is documented in packages/qin-runtime-core/QIN_NPM_COMPATIBILITY_POLICY.md.
- host/runtime capability boundary is documented in packages/qin-runtime-core/QIN_HOST_CAPABILITY_MODEL.md.
- JS-on-JVM support priority and deferred-feature policy is documented in packages/qin-runtime-core/QIN_JS_ON_JVM_FEASIBILITY.md.
- Qin frontend lifecycle policy is Qin-owned; Vite can be studied as prior art, but Qin does not use it as a bridge or fallback.
- CSSTS integration policy is documented in packages/qin-runtime-core/QIN_CSSTS_INTEGRATION_MODEL.md.
- See packages/qin-runtime-core/QIN_BACKEND_MODEL.md.
- Builtin object strategy is documented in packages/qin-runtime-core/QIN_BUILTINS_STRATEGY.md.
- Async/concurrency model is documented in packages/qin-runtime-core/QIN_ASYNC_MODEL.md.
- Phase 1: selected ES syntax + stable ESM core semantics + Java-backed runtime APIs.
- Phase 1 non-goal: full ECMAScript and full ESM edge-case compatibility.
- Phase 1 non-goal: pretending Node compatibility is the platform standard.
- Reason: this is an engineering phasing strategy, not a JVM limitation. We prioritize a stable core first, then expand compatibility incrementally where real packages require it.
| Dimension | Browser/Node JS | Bun | Kotlin/JVM | Qin |
|---|---|---|---|---|
| Source language | JavaScript / TypeScript | JavaScript / TypeScript | Kotlin | ESM-style Qin |
| Primary goal | Run JS | Run JS faster and provide toolchain | Modern JVM language | Modern ESM-style JVM language |
| Runtime foundation | JS engine + host runtime | JavaScriptCore + Zig host runtime | JVM | JVM |
| Backend ecosystem | Node/npm | Node/npm | .class / Java ecosystem |
.class / Java ecosystem |
| Node compatibility pressure | High | High | None | None by default |
| Output artifact | interpreted / bundled JS | interpreted / bundled JS | .class |
.class |
| Spring integration model | indirect bridges | indirect bridges | native | native target |
| Language semantics owner | ECMAScript + host | ECMAScript + Bun host | Kotlin | Qin |
Operationally:
- Bun is best understood as a JS runtime/toolchain implemented largely in Zig.
- Qin is best understood as an ESM-style source language compiled onto the JVM.
- So Qin is not "Java-written Bun" and not "JVM-hosted Node".
- Qin is closer to "ESM-syntax Kotlin-like language for the JVM" than to a JS engine.
There is no mainstream language today that is exactly the same as Qin.
The closest comparisons are split across different dimensions:
- Kotlin: closest on backend platform strategy
- Scala / Groovy: similar on "new language on JVM" category
- TypeScript: closest on source authoring familiarity
- ClojureScript / ReScript / Elm: similar in "source language compiles to JS" direction
- Bun / Deno / Node: useful comparison targets, but not the same category
Kotlin is closest on backend platform strategy: independent language, compiles to JVM .class, integrates naturally with Spring / Java ecosystem, but it is not ESM-style at the source language level.
Scala / Groovy are close in the "new language on JVM" category: JVM-native backend language position, strong .class ecosystem integration, but not designed around ESM-style fullstack authoring.
TypeScript is closest on source authoring familiarity: modern JS/ESM-style code organization and decorator-oriented developer expectations, but it normally targets JS runtimes rather than JVM .class.
ClojureScript / ReScript / Elm are similar in the "source language compiles to JS" direction, but they are not trying to make JVM .class the primary backend artifact.
Bun / Deno / Node are useful comparison targets mainly for what Qin is not: they are JS runtimes/toolchains, while Qin is a new language platform with its own runtime boundary.
So the best mental model is:
- backend category: closer to Kotlin than to Node
- source-language feel: closer to ESM/TypeScript than to Kotlin syntax
- product shape: a fullstack language with target-specific backends, not a JS runtime clone
Qin intentionally keeps:
- ES-style module authoring with
import/export - modern JS-like expression syntax
- decorators as the source-level annotation model
- familiar builtin names such as
console,JSON,Math,Array,Object - frontend/backend authoring style convergence
Qin intentionally does not promise, at least in the current architecture phase:
- full ECMAScript engine parity
- full Node runtime compatibility
- full prototype-chain edge-case fidelity
- CommonJS behavior
- "any npm package should just run" without adaptation
- browser or Node loader behavior as the definition of correctness
- Promise-first /
async-viral programming model for backend code
The design intent is:
- keep the productive parts of ESM authoring experience
- keep Qin semantics stable and documentable
- map backend execution cleanly to JVM +
.class - avoid being trapped by Node compatibility as the platform definition
- preserve Java/Kotlin-like synchronous backend ergonomics by default
- add Node-adjacent compatibility only as an incremental layer when ecosystem pressure makes it worthwhile
These folders are current normative technical architecture. They are not the final preferred primary end-user mental model for Qin application authoring. See packages/qin-runtime-core/QIN_APP_MODEL.md.
shared/: shared code and shared contractsapp/: frontend static assets root (/indexresolves toapp/indexorapp/index.html)- backend entry: Java defaults to
src/Main.java(with compatibility candidates), Qin defaults usemain/main.qinand other built-in candidates
app/(frontend): can import JS modules, cannot importjava:modulesmain/(backend): can importjava:and JS modulesshared/(shared): cannot importjava:or JS modules- Violations fail at compile time with policy error codes
- Location:
qin/packages/qin-runtime-core - Name:
qin-runtime-core - Purpose: Qin runtime orchestration layer (Java runtime semantics, ES-style syntax)
- Keep
slime-javaparser frontend as shared infrastructure. - Keep compiler backends (
qin-lang-backend-jvmandqin-lang-backend-js) as independent modules. - Put project-level orchestration (layout conventions, bootstrap CLI) in a dedicated runtime package.
Use com.qin.runtime.core.QinRuntimeMain to parse .ts, .js, and .qin Qin source inputs through the Qin pipeline and emit .class/.js outputs.
Qin is a JS/ESM-syntax, JVM-kernel compiled language.
- Qin is not a full JavaScript engine.
- Qin does not aim for Node compatibility.
- Qin does not treat Node semantics as normative for language or runtime behavior.
- Qin uses Class-File API to emit JVM
.classartifacts. - Qin defines its own backend/runtime standard on the JVM.
- ESM-only module model in this phase.
- Supported module syntax baseline:
import/export(ESM). - Not supported as language spec: CommonJS (
require,module.exports,exports.*). - Any accidental CJS behavior seen during experiments is non-normative and not a compatibility promise.
- If source depends on CJS semantics, Qin may fail at parse/semantic/lowering/runtime stages.
- Node runtime APIs are out of scope in this phase (
process,Buffer,__dirname,fs,path,node:*, etc.). qin installcan fetch npm packages, but "can install" != "can run".- Runtime compatibility depends on whether package code stays inside Qin-supported ESM + syntax/runtime subset.
- npm ecosystem behavior is never the normative definition of Qin semantics.
Qin should treat npm as a package source, not as the definition of the runtime.
That means:
- compatible npm packages may enter the Qin compile graph
.ts/.js/.qinpackage sources may be compiled by Qin- backend-compatible packages may be lowered into the JVM target and participate in
.classoutputs - frontend-compatible packages may be lowered into JS outputs
Important boundary:
- this does not mean every npm package is supported
- support is source-compatibility-based, not registry-based
- packages that depend on CJS, Node-only APIs, native addons, or unsupported JS runtime behavior may still fail by design
So the correct rule is:
- Qin aims to compile compatible npm packages, not to promise blind npm ecosystem parity
- Qin runtime uses a single function-construction entrypoint:
Global.__qin_make_function__. - Frontend lowers supported JS function AST into a runtime function definition object, then routes through that entrypoint.
- Runtime decides whether to instantiate:
- interpreted JS function (AST-driven, generic semantics path), or
- fallback callable (for unsupported/over-budget shapes).
- This is a structural design, not package-specific behavior:
- no npm package hardcode,
- no library shim mapping,
- no package-name condition branches in parser/lowering/runtime.
Safety guard for large modules:
- Qin applies a lowering budget for runtime function definitions.
- For very large source units, function-model lowering is automatically disabled to prevent JVM bytecode method-size overflow.
- This keeps pipeline stability while preserving the same architecture and entrypoint.
Project zoning rules (compile-time hard rules):
app/(frontend): JS/ESM imports allowed,java:imports denied.main/(backend):java:and JS imports allowed.shared/: platform-specific imports denied (java:and JS package imports).
Run model:
qin runwithout args followsqin.config.jsand convention candidates..jsentries run through Qin runtime (qin-runtime-core)..javaentries run through Java compile/run flow.
ESM diagnostics:
- Link and semantic diagnostics:
ESM2xxx - Runtime feature gates:
ESM3xxx
Reference implementation details live in:
packages/qin-lang-module-policy/README.mdpackages/qin-lang-sema-esm/README.mdpackages/qin-runtime-core/README.md
qin install now supports mixed dependency sources in one workflow:
- npm-first resolution (Node-free installer implemented in Java)
- Maven fallback when npm package cannot be resolved
- Automatic write-back to
qin.config.js
qin.config.js should be treated as the canonical Qin project manifest, not only as a loose config file.
In the current architecture it defines:
- project/package identity:
name,version,description - source/runtime entry selection:
entry - dependency surface:
dependencies,devDependencies,repositories - workspace shape:
packages - target/runtime/build knobs:
java,graalvm,frontend,output,port
So Qin is converging on one manifest for:
- package identity
- mixed npm + Maven dependency declaration
- workspace package discovery
- module-root and runtime/build coordination
-
qin install <pkg...>- For bare package names (for example
mitt,lodash-es), Qin tries npm first. - If npm cannot resolve that package, Qin falls back to Maven Central lookup.
- Installed dependencies are recorded into
qin.config.js.
- For bare package names (for example
-
qin install org.example:artifact[:version]- Explicit Maven coordinates go directly to Maven resolution.
- Added to
qin.config.js, then resolved byqin synclogic.
-
qin install(no package names)- Executes install using dependencies already declared in
qin.config.js. - npm-style entries are installed to
node_modulesby Qin's Java npm installer. - Maven-style entries are resolved using the existing
syncpipeline. - This is the unified update path for
main/backend JS + Java dependency environment.
- Executes install using dependencies already declared in
- npm dependencies: key is npm package name, value is npm version
- Example:
"mitt": "3.0.1"
- Example:
- Maven dependencies: key is Maven coordinate (
groupId:artifactId), value is Maven version- Example:
"org.jsoup:jsoup": "1.18.1"
- Example:
This allows Qin projects to manage npm + Maven dependencies together while keeping runtime constraints explicit (Node APIs are still out of scope unless Qin runtime explicitly supports them).
qin installis a dependency acquisition and lock/write-back workflow.- Runtime execution still follows Qin language/runtime constraints above (ESM-first, no CJS guarantee, no Node API guarantee).
- If an npm package requires CJS or Node-only APIs, install may succeed but compile/run can still fail by design.
- Package-manager convenience must not be confused with platform compatibility goals.
Notes:
app/frontend package behavior is intentionally not changed in this phase.main/backend JS and Java now follow one dependency update entrypoint:qin install.