Bytecode (בייטקוד), ידוע גם בשם p-code (קוד נייד - portable code), הוא צורה של סט פקודות אשר תוכנן עבור ביצוע יעיל על ידי מפרש תוכנה. להבדיל מקוד מקור הקריא על ידי בני אדם, בייטקוד מורכב מקודים נוּמריים קומפקטיים, קבועים, והפניות (references) - בדרך כלל כתובות נומריות; אשר מקודדים את תוצאות הניתוח התחבירי והסמנטי של דברים כגון טיפוס הנתונים, תחום ההכרה (scope), ועומק הקינון (nesting) של רכיבי תוכנה.
מקור השם bytecode הוא מסטים של פקודות אשר מורכבים מ-opcodes באורך של byte אחד, שאחריהם יכולים לבוא פרמטרים אופציונליים. ייצוגי ביניים כמו bytecode עשויים להיות הפלט של מימושים של שפות תכנות על מנת להקל על עבודת המפרש, או כדי להוריד את התלות בחומרה ובמערכת ההפעלה, בכך שהם מאפשרים לאותו קוד לרוץ על גבי פלטפורמות שונות. לעיתים קרובות, בייטקוד יכול לרוץ ישירות על גבי מכונה וירטואלית (כלומר, המפרש), אבל יש מקרים בהם הבייטקוד מהודר הלאה לשפת מכונה לצורך שיפור הביצועים.
מאחר שהוראות הבייטקוד מעובדות על ידי תוכנה, הן יכולות להגיע ברמות שונות של מורכבות. עם זאת, בדרך כלל הן דומות להוראות חומרה מסורתיות; מכונות מחסנית (stack machines) הן הנפוצות ביותר, אבל נבנו גם מכונות רגיסטרים (register machines) וירטואליות. חלקים שונים של התוכנית יכולים להישמר בקובצי bytecode נפרדים, בדומה לקובצי object המקושרים על ידי linker, אבל שלא כמו קובצי object, קובצי bytecode נטענים דינאמית בזמן ריצה.
תוכניות בייטקוד ניתנות להרצה על ידי ביצוע ניתוח תחבירי (parsing) וביצוע ישיר של ההוראות אחת אחרי השנייה. מפרשי בייטקוד שעובדים בצורה כזאת הם מאוד פורטביליים (יבילים). מערכות אחרות שנקראות dynamic translators (מתרגמים דינאמיים), או just-in-time (JIT) compilers (מהדרים "בדיוק בזמן"), מתרגמות בייטקוד לשפת מכונה בזמן ריצה, ברגע שהוא נדרש. זה הופך את המכונה הווירטואלית ללא פורטבילית, אבל לא גורם לאיבוד הפורטביליות של הבייטקוד עצמו. לדוגמה, קוד בשפות Java ו-Smalltalk בדרך כלל נשמר בפורמט בייטקוד, אשר בשלב מאוחר יותר עובר הידור JIT כדי לתרגם את הקוד לשפת מכונה לפני ההרצה שלו. אופן פעולה כזה גורר עיכוב לפני תחילת הריצה של התוכנית, בזמן שהבייטקוד עובר הידור לשפת מכונה (native), אבל משפר משמעותית את מהירות הריצה עצמה בהשוואה לפירוש ישיר של קוד המקור – בדרך כלל בכמה סדרי גודל.
בזכות השיפור הנ"ל בביצועים, כיום הרבה מימושים של שפות תכנות מריצים תוכניות בשני שלבים – תחילה מהדרים את קוד המקור לבייטקוד, ואז מעבירים את הבייטקוד למכונה וירטואלית. לפיכך קיימות מכונות וירטואליות עבור השפות Forth, PHP, Python, Java ו-TCL. לעומת זאת, המימושים של השפות Perl ו-Ruby (גרסה 1.8) פועלים על ידי מעבר על ייצוג של abstract syntax tree אשר מופק מקוד המקור.